DEV Community

Siddharth Shanker
Siddharth Shanker

Posted on

Documentation for Deployment of Applications and Managing with Supervisor

This involves deployment and integration of Django app, Postgres, Gunicorn, Nginx and Supervisor(used for managing gunicorn instances)

Copy the Django application from LOCAL to REMOTE server

Run this command on local system

scp -r <path-to-django-app-on-local>  ubuntu@<ip address>:<path-where-you-want-to-copy-to-on-remote>
Enter fullscreen mode Exit fullscreen mode

Log into Remote Server and install libraries from UBUNTU Repositories

sudo apt update
sudo apt install python3-venv python3-dev libpq-dev postgresql postgresql-contrib nginx curl
Enter fullscreen mode Exit fullscreen mode

Setting up PostgreSQL DB and User

Log into postgres session

sudo -u postgres psql
Enter fullscreen mode Exit fullscreen mode

Inside Postgres Prompt setting up DB and user

CREATE DATABASE <db-name>;

CREATE USER <username> WITH PASSWORD '<password>';

ALTER ROLE <username> SET client_encoding TO 'utf8';

ALTER ROLE <username> SET default_transaction_isolation TO 'read committed';

ALTER ROLE <username> SET timezone TO 'UTC';

GRANT ALL PRIVILEGES ON DATABASE <db_name> TO <username>;
Enter fullscreen mode Exit fullscreen mode

Setting up Django-Project and Virtual Environment

Create Virtual Environment for Django Project and activate

python3 -m venv <environment-name>

source <environment-name>/bin/activate
Enter fullscreen mode Exit fullscreen mode

Install psycopg for postgres support

 pip install psycopg2-binary
Enter fullscreen mode Exit fullscreen mode

Install gunicorn

pip install gunicorn
Enter fullscreen mode Exit fullscreen mode

Now Integrating PostgreSQL

Go to Configs and change the database values to following

DATABASES = {
                    'default': {
                        'ENGINE': 'django.db.backends.postgresql_psycopg2',
                        'NAME': 'db-name',
                        'USER': 'username',
                        'PASSWORD': 'password',
                        'HOST': 'localhost',
                        'PORT': '',
                    }
            }
Enter fullscreen mode Exit fullscreen mode

Making exception for port 8000

sudo ufw allow 8000
Enter fullscreen mode Exit fullscreen mode

Run following commands to check integrity and collect static

python manage.py makemigrations

python manage.py migrate

python manage.py runserver

python manage.py collectstatic
Enter fullscreen mode Exit fullscreen mode

SETTING UP GUNICORN FOR SUPERVISOR (IF NOT SETUP)

Create a gunicorn file managed by supervisor inside bin folder of virtual env

cd <path to env of django app>/bin

sudo nano gunicorn_supervisor
Enter fullscreen mode Exit fullscreen mode

PASTE the following bash script configuration to run Gunicorn and make changes for individual sock files, path to project, user/group etc accordingly.

#!/bin/bash


DIR=<path to django app directory where manage.py is present>  #Directory where project is located
USER=ubuntu   #User to run this script as
GROUP=ubuntu  #Group to run this script as
WORKERS=3     #Number of workers that Gunicorn should spawn
SOCKFILE=unix:/run/<project-name>.sock  #This socket file will communicate with Nginx 
DJANGO_SETTINGS_MODULE=<project-dir-name-which-contains-settings.py>.settings   #Which Django setting file should use
DJANGO_WSGI_MODULE=<project-dir-name-which-contains-wsgi.py>.wsgi           #Which WSGI file should use
LOG_LEVEL=debug
cd $DIR
source <path to venv>/bin/activate  #Activate the virtual environment
export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
export PYTHONPATH=$DIR:$PYTHONPATH


#Command to run the progam under supervisor
exec <path-to-venv>/bin/gunicorn ${DJANGO_WSGI_MODULE}:application \
--workers $WORKERS \
--user=$USER \
--group=$GROUP \
--bind=$SOCKFILE \
--pythonpath <path-to-venv>/bin/python \
--log-level=$LOG_LEVEL \
--access-logfile=/var/log/supervisor/<name-the-file>.log \
--error-logfile=/var/log/supervisor/<name-the-file>.log

Enter fullscreen mode Exit fullscreen mode

Give Permissions for this file to read-write-execute

sudo chmod 755 gunicorn_supervisor
Enter fullscreen mode Exit fullscreen mode

Creating Supervisor program for managing the Gunicorn Instances

sudo apt-get install supervisor
Enter fullscreen mode Exit fullscreen mode

Creating a conf file for supervisor to watch for Gunicorn Instance of the django app

cd /etc/supervisor/conf.d/

sudo nano <app-name>.conf
Enter fullscreen mode Exit fullscreen mode

Paste the following and make changes accordingly for user, logs and program name

[program:<program-name>]
command=<path-to-app-venv>/bin/gunicorn_supervisor
user=root
autostart=true
autorestart=true
stderr_logfile=/var/log/supervisor/<name-of-error-log-file>.log
stdout_logfile=/var/log/supervisor/<name-of-output-log-file>.log

Enter fullscreen mode Exit fullscreen mode

Run the following commands

sudo supervisorctl reread
sudo supervisorctl update
Enter fullscreen mode Exit fullscreen mode

You can also check the status of your app or start, stop or restart it using supervisor.

sudo supervisorctl status <program-name>
sudo supervisorctl start <program-name>
sudo supervisorctl stop <program-name>
sudo supervisorctl restart <program-name>
Enter fullscreen mode Exit fullscreen mode

NGINX Installation and Setup

Creating configuration for Nginx to proxy pass Gunicorn

sudo nano /etc/nginx/sites-available/<project-name>
Enter fullscreen mode Exit fullscreen mode

Now Paste this and make changes accordingly linking correct sock file

server {
    listen 80;
    server_name server_domain_or_IP;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root <path-to-dir-which-contains-static-dir>;
    }

    location / {
        include proxy_params;
        proxy_pass http://unix:/run/<name-of-sock-file>;
    }
}
Enter fullscreen mode Exit fullscreen mode

If there are multiple applications being served from same domain/IP then:-

1. Make individual app files within nginx
2. Change listening port of server i.e every app will listen on individual ports

    eg:- app1                               app2

        server {                            server {
            listen 80;                          listen 81;
            ....                                ....
        }                                   }
Enter fullscreen mode Exit fullscreen mode
sudo ln -s /etc/nginx/sites-available/<project-name> /etc/nginx/sites-enabled
Enter fullscreen mode Exit fullscreen mode

To save the configs and check for any errors

sudo nginx -t
Enter fullscreen mode Exit fullscreen mode

Restart Nginx

sudo systemctl restart nginx
Enter fullscreen mode Exit fullscreen mode

Finally, you need to open up your firewall to normal traffic on port 80. Since you no longer need access to the development server, you can remove the rule to open port 8000

sudo ufw delete allow 8000
sudo ufw allow 'Nginx Full'
Enter fullscreen mode Exit fullscreen mode

Troubleshooting Nginx, Gunicorn and Supervisor

Top comments (0)