Django Deployment Django deployment instructions. Nginx + Gunicorn + Supervisor on Linux (Ubuntu)


Example

Three basic tools.

  1. nginx - free, open-source, high-performance HTTP server and reverse proxy, with high performance;
  2. gunicorn - 'Green Unicorn' is a Python WSGI HTTP Server for UNIX (needed to manage your server);
  3. supervisor - a client/server system that allows its users to monitor and control a number of processes on UNIX-like operating systems. Used when you app or system crashes, restarts your django / celery / celery cam, etc;

In order ot make it simple, let's assume your app is located in this directory: /home/root/app/src/ and we're gonna use root user (but you should create separate user for your app). Also our virtualenvironment will be located in /home/root/app/env/ path.

NGINX

Let's start with nginx. If nginx is not already on machine, install it with sudo apt-get install nginx. Later on you have to create a new config file in your nginx directory /etc/nginx/sites-enabled/yourapp.conf. If there is a file named default.conf - remove it.

Bellow code to a nginx conf file, which will try to run your service with using socket file; Later on there will be a configuration of gunicorn. Socket file is used here to communicate between nginx and gunicorn. It can also be done with using ports.

# your application name; can be whatever you want
upstream yourappname {
    server        unix:/home/root/app/src/gunicorn.sock fail_timeout=0;
}

server {
    # root folder of your application
    root        /home/root/app/src/;
 
    listen        80;
    # server name, your main domain, all subdomains and specific subdomains
    server_name   yourdomain.com *.yourdomain.com somesubdomain.yourdomain.com
 
    charset       utf-8;

    client_max_body_size                        100m;
 
    # place where logs will be stored;
    # folder and files have to be already located there, nginx will not create
    access_log        /home/root/app/src/logs/nginx-access.log; 
    error_log         /home/root/app/src/logs/nginx-error.log;
    
    # this is where your app is served (gunicorn upstream above)
    location / {
        uwsgi_pass  yourappname;
        include     uwsgi_params; 
    }

    # static files folder, I assume they will be used
    location /static/ {
        alias         /home/root/app/src/static/;
    }
 
    # media files folder
    location /media/ {
        alias         /home/root/app/src/media/;
    }

}

GUNICORN

Now our GUNICORN script, which will be responsible for running django application on server. First thing is to install gunicorn in virtual environment with pip install gunicorn.

#!/bin/bash

ME="root"
DJANGODIR=/home/root/app/src # django app dir
SOCKFILE=/home/root/app/src/gunicorn.sock # your sock file - do not create it manually
USER=root
GROUP=webapps
NUM_WORKERS=3 
DJANGO_SETTINGS_MODULE=yourapp.yoursettings
DJANGO_WSGI_MODULE=yourapp.wsgi  
echo "Starting $NAME as `whoami`"
 
# Activate the virtual environment
cd $DJANGODIR

source /home/root/app/env/bin/activate
export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
export PYTHONPATH=$DJANGODIR:$PYTHONPATH
 
# Create the run directory if it doesn't exist
RUNDIR=$(dirname $SOCKFILE)
test -d $RUNDIR || mkdir -p $RUNDIR
 
# Start your Django Gunicorn
# Programs meant to be run under supervisor should not daemonize themselves (do not use --daemon)
exec /home/root/app/env/bin/gunicorn ${DJANGO_WSGI_MODULE}:application \
  --name root \
  --workers $NUM_WORKERS \
  --user=$USER --group=$GROUP \
  --bind=unix:$SOCKFILE \
  --log-level=debug \
  --log-file=-

in order to be able to run gunicorn start script it has to have execution mode enabled so

sudo chmod u+x /home/root/app/src/gunicorn_start

now you will be able to start your gunicorn server with just using ./gunicorn_start


SUPERVISOR

As said in the beginning, we want our application to be restarted when fails by a supervisor. If supervisor not yet on server install with sudo apt-get install supervisor.

At first install supervisor. Then create a .conf file in your main directory /etc/supervisor/conf.d/your_conf_file.conf

configuration file content:

[program:yourappname]
command = /home/root/app/src/gunicorn_start
user = root
stdout_logfile = /home/root/app/src/logs/gunicorn_supervisor.log
redirect_stderr = true

Quick brief, [program:youappname] is required at the beginning, it will be our identifier. also stdout_logfile is a file where logs will be stored, both access and errors.

Having that done we have to tell our supervisor that we have just added new configuration file. To do it, there is different process for different Ubuntu version.

For Ubuntu version 14.04 or lesser than it, simply run those commands:

sudo supervisorctl reread -> rereads all config files inside supervisor catalog this should print out: yourappname: available

sudo supervisorctl update -> updates supervisor to newly added config files; should print out yourappname: added process group

For Ubuntu 16.04 Run:

sudo service supervisor restart

and in order to check if your app is running correctly just run

sudo supervisorctl status yourappname

This should display :

yourappname RUNNING pid 18020, uptime 0:00:50

To get live demonstration of this procedure, surf this video.