Jun 15, 2024

Installing multiple versions of node and npm using nvm

 Environment: Ubuntu / Debian

$curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash


add following on your .bash_profile or .bashrc if not added automatically when running above command 

export NVM_DIR="$HOME/.nvm"

[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  

[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  


Logout and login terminal 


Now if you want to install node version 20.10.0 then issue 

$nvm install 20.10.0

 

Now if you want to use some other version (eg. node version 21.0.0) and want to use it

$  nvm ls-remote

$ nvm  install 21.0.0

$ nvm use  21.0.0


Containerizing Node.js, Django, Postgres, Celery, RabbitMQ and Elasticsearch

 

 

1. Dockerfile for Nextjs front end placed parallel to package.json file

FROM node:20.12.2-alpine
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "run", "dev"]

1.a. .env

NEXT_PUBLIC_BASE_URL=http://192.168.x.x:8000

 

2. Dockerfile for Python backend placed above src folder 

FROM python:3.11.4-alpine3.18
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
WORKDIR /usr/src/app
COPY ./src/requirements/requirements_dev.txt /usr/src/app
COPY ./src/requirements/base.txt /usr/src/app
RUN pip install --upgrade pip && \
    apk update && \
    apk add postgresql-dev gcc python3-dev musl-dev jpeg-dev zlib-dev curl && \
    pip install -r requirements_dev.txt
COPY ./src/.env /usr/src/app
RUN mkdir /usr/src/app/logs
COPY ./entrypoint.sh /usr/src/app
RUN sed -i 's/\r$//g' ./entrypoint.sh
RUN chmod 777 ./entrypoint.sh
COPY ./src /usr/src/app/
RUN chmod 777 ./es_index.py
ENTRYPOINT ["./entrypoint.sh"]

2.a. entrypoint.sh

#!/bin/sh

export POSTGRES_HOST="db"

if [ $DATABASE = "postgres" ]
then
    echo "Waiting for postgres to load..."

    while ! nc -z $POSTGRES_HOST $POSTGRES_PORT; do
        sleep 0.1
    done

    echo "postgres ready to run"
    python manage.py makemigrations
    python manage.py migrate --no-input
fi

python manage.py createsuperuser --noinput --username $DJANGO_SUPERUSER_USERNAME --email $DJANGO_SUPERUSER_EMAIL
python es_index.py

exec "$@"


2.b. vi .env

# secret key
SECRET_KEY=ac6cd19772005f224cefb220060037bf15f35a6e3e1826a1095a26fc

# database stuffs
DATABASE=postgres

DB_ENGINE=django.db.backends.postgresql
POSTGRES_DB=courses
POSTGRES_USER=postgres
POSTGRES_PASSWORD=xxxxx
POSTGRES_PORT=5432
POSTGRES_HOST=db

# superuser setup
DJANGO_SUPERUSER_USERNAME=admin
DJANGO_SUPERUSER_PASSWORD=admin
DJANGO_SUPERUSER_EMAIL=admin@gmail.com

# smtp setup
EMAIL_HOST_USER=courses@xxxxxx.org
EMAIL_HOST_PASSWORD=titygjzkngqtzoek

# celery stuffs
#CELERY_BROKER_URL=amqp://guest:guest@localhost:15672/
#CELERY_RESULT_BACKEND=db+postgresql://postgres:admin@localhost:5432/celery_tasks

# Adjust for dockerizatin
CELERY_BROKER_URL=amqp://myuser:mypassword@rabbitmq:5672
CELERY_RESULT_BACKEND=db+postgresql://postgres:admin@db:5432/celery_tasks

ADMIN_USER=xxxxxx@xxxxxx.org

# elastic
#ES_HOST=localhost
ES_HOST=elasticsearch
ES_NUMBER_OF_SHARDS=1
ES_NUMBER_OF_REPLICAS=0
ES_USE_SSL=False
ES_PORT=9200
ES_INDEX=seepalaya


    apk update && \
    apk add postgresql-dev gcc python3-dev musl-dev jpeg-dev zlib-dev && \
    pip install -r requirements_dev.txt
COPY ./src/.env /usr/src/app
RUN mkdir /usr/src/app/logs
COPY ./src /usr/src/app/


3.a .env

similar to above 

 

4. Dockerfile for Postgres

FROM postgres:15.7-alpine3.18
ENV PG_MAX_WAL_SENDERS 8
ENV PG_WAL_KEEP_SEGMENTS 8

#Set timezone
ENV TZ=Asia/Kathmandu
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# Copy the custom initialization script to the Docker image
COPY create_celery.sh /docker-entrypoint-initdb.d/
COPY *.sql /tmp/
COPY populate_ep.sh /docker-entrypoint-initdb.d/

# Grant execution permissions to the script
RUN chmod +x /docker-entrypoint-initdb.d/create_celery.sh
RUN chmod +x /docker-entrypoint-initdb.d/populate_ep.sh

 

4a. create_celery.sh

#!/bin/bash
set -e

# Create additional databases
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL
    CREATE DATABASE celery_tasks;
EOSQL

4b. populate_ep.sh

#!/bin/bash
set -e

# Function to check if the database exists
db_exists() {
    psql -U "$POSTGRES_USER" -tc "SELECT 1 FROM pg_database WHERE datname = 'pustakalaya'" | grep -q 1
}

# Create the database if it does not exist
if ! db_exists; then
    psql -U "$POSTGRES_USER" -c "CREATE DATABASE pustakalaya"
fi

# Create the user and grant privileges
psql -U "$POSTGRES_USER" <<-EOSQL
    DO \$\$
    BEGIN
        IF NOT EXISTS (SELECT FROM pg_catalog.pg_user WHERE usename = 'pustakalaya_user') THEN
            CREATE USER pustakalaya_user WITH PASSWORD 'pustakalaya123';
        END IF;
    END
    \$\$;
    GRANT ALL PRIVILEGES ON DATABASE pustakalaya TO pustakalaya_user;
EOSQL

psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname=pustakalaya < /tmp/pustakalaya.sql


4.c. .env

POSTGRES_DB=courses
POSTGRES_USER=postgres
POSTGRES_PASSWORD=xxxxx
            
    

 

5. docker-compose.yml

version: "3.8"
services:
  db:
    build:
      context: seepalaya-new-database
      dockerfile: Dockerfile.postgres
    container_name: seepalaya-db
    env_file:
      - ./seepalaya-new-database/.env
    volumes:
      - ./db/:/var/lib/postgresql/
    networks:
      - seepalaya-new
    restart: always


  seepalaya-backend:
    build:
      context: seepalaya-new-backend
      dockerfile: Dockerfile
    container_name: seepalaya-backend
    command: "python manage.py runserver 0.0.0.0:8000"
    ports:
      - 8000:8000
    env_file:
      - ./seepalaya-new-backend/src/.env
    environment:
      - CELERY_BROKER_URL=amqp://myuser:mypassword@rabbitmq:5672
    depends_on:
      - db
    networks:
      - seepalaya-new
    restart: always

  rabbitmq:
    image: rabbitmq:3-management
    ports:
      - "5672:5672"
    environment:
      - RABBITMQ_DEFAULT_USER=myuser
      - RABBITMQ_DEFAULT_PASS=mypassword
    networks:
      - seepalaya-new
    restart: always

 seepalaya-celery:
    build:
      context: seepalaya-new-celery
      dockerfile: Dockerfile
    container_name: seepalaya-celery
    command: celery -A config worker -l info
    environment:
      - CELERY_BROKER_URL=amqp://myuser:mypassword@rabbitmq:5672
    depends_on:
      - rabbitmq
      - seepalaya-backend
    networks:
      - seepalaya-new
    restart: always

  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.12.1
    environment:
      - discovery.type=single-node
    ports:
      - "9200:9200"
    networks:
      - seepalaya-new
    restart: always
 
  seepalaya-front:
    build:
      context: seepalaya_new
      dockerfile: Dockerfile     
    container_name: seepalaya-front
    env_file:
      - ./seepalaya_new/.env
    ports:
      - "3000:3000"
    networks:
      - seepalaya-new
    restart: always

networks:
  seepalaya-new:
    driver: bridge

Apr 26, 2024

 

Installing multiple versions of python on linux using pyenv and create virtual environment.

python3 --version

 

 2. Install version 3.10.13 (chose the version you need)

cd
sudo apt install curl git gcc make libssl-dev libbz2-dev
sudo apt install  python3-setuptools
sudo apt install python3-pip
curl https://pyenv.run | bash
cd .pyenv/bin
./pyenv install --list
./pyenv install 3.10.13
cd ~/.pyenv/versions/3.10.13/bin/
./python3.10 --version

cd ~/.pyenv/versions/3.10.13/bin/
./python3.10 -m venv ~/.venv310


4. To activate virtual environment

cd
source .venv310/bin/activate
(.venv310):~$

 








 


Apr 25, 2024

 

Top 4 steps to secure debian / ubuntu

grep security /etc/apt/sources.list > /tmp/security.list
sudo apt-get upgrade -oDir::Etc::Sourcelist=/tmp/security.list'

 

apt-get install rsyslog
apt-get install fail2ban

 

vi /etc/myufw.sh

#!/bin/bash
ufw=/usr/sbin/ufw
$ufw disable
$ufw default deny incoming
$ufw default allow outgoing
$ufw allow ssh
$ufw allow https
$ufw allow 5000
$ufw allow 3000
$ufw allow 7000
$ufw - force enable

$sudo chmod +x /etc/myufw.sh

$ sudo chmod /etc/myufw.sh

$ sudo iptables -L -n

 

vi /etc/ssh/sshd_config and check following 2 lines
PasswordAuthentication no
PermitRootLogin no

$sudo systemctl restart ssh