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>
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
Setting up PostgreSQL DB and User
Log into postgres session
sudo -u postgres psql
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>;
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
Install psycopg for postgres support
pip install psycopg2-binary
Install gunicorn
pip install gunicorn
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': '',
}
}
Making exception for port 8000
sudo ufw allow 8000
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
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
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
Give Permissions for this file to read-write-execute
sudo chmod 755 gunicorn_supervisor
Creating Supervisor program for managing the Gunicorn Instances
sudo apt-get install supervisor
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
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
Run the following commands
sudo supervisorctl reread
sudo supervisorctl update
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>
NGINX Installation and Setup
Creating configuration for Nginx to proxy pass Gunicorn
sudo nano /etc/nginx/sites-available/<project-name>
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>;
}
}
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;
.... ....
} }
sudo ln -s /etc/nginx/sites-available/<project-name> /etc/nginx/sites-enabled
To save the configs and check for any errors
sudo nginx -t
Restart Nginx
sudo systemctl restart nginx
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'
Top comments (0)