Django : Gunicorn + wsgi + nginx + Fabric

Update your system

$ sudo apt-get update
$ sudo apt-get upgrade

Folder Structure

  • all Webapps will be stored in /webapps/ folder
  • nginx files serves from /webapps/nginx/ folder
  • apache files servers from /webapps/apache folder
  • all sites will be on
    • nginx
      • /webapps/nginx/sites/
      • /webapps/nginx/sites/
    • apache
      • /webapps/apache/sites/
      • /webapps/apache/sites/
  • all python, nodejs other application will be on
    • /webapps/nginx/sites/
    • /webapps/nginx/sites/

Application Folder Structure

  • src
      • PROJECTX
        • settings
          • settings .py
  • logs
    • nginx-error.log
    • nginx-access.log
    • gunicorn_supervisor.log
  • bin
    • activate
    • gunicorn
    • gunicor_start
    • python
  • run
    • gunicorn.sock
  • lib
  • lib64
  • local
  • wsgi
  • include
  • media
  • static

Application User

Its best security practice to use per apps user to host application

create a new user and add to default application groups

sudo groupadd --system webapps
sudo useradd --system --gid webapps --home /webapps/nginx/sites/ project_name


sudo apt-get install python-virtualenv

Create and activate an environment for your application

cd /webapps/
virtualenv project_name
cd project_name 

Install Django

pip install django

Create an empty Django project. startproject project_name


 pip install gunicorn


cd /web/nginx/sites/
touch app.wsgi

In app.wsgi

activate_this = '/web/nginx/sites/'

execfile(activate_this, dict(__file__=activate_this))

import sys
sys.path.insert(0, '/web/nginx/sites/')

from api import app as application

Test Gunicorn

cd /web/nginx/sites/

gunicorn app.wsgi:application --bind

Create Gunicron Start Script

cd /web/nginx/sites/
touch gunicorn_start


NAME="project_name"                                  # Name of the application
DJANGODIR=/web/nginx/sites/            # Django project directory
SOCKFILE=/web/nginx/sites/  # we will communicte using this unix socket
USER=project_name                                        # the user to run as
GROUP=webapps                                     # the group to run as
NUM_WORKERS=3                                     # how many worker processes should Gunicorn spawn
DJANGO_SETTINGS_MODULE=project_name.settings             # which settings file should Django use
DJANGO_WSGI_MODULE=project_name.wsgi                     # WSGI module name

echo "Starting $NAME as `whoami`"

# Activate the virtual environment
source ../bin/activate

# Create the run directory if it doesn't exist
test -d $RUNDIR || mkdir -p $RUNDIR

# Start your Django Unicorn
# Programs meant to be run under supervisor should not daemonize themselves (do not use --daemon)
exec ../bin/gunicorn ${DJANGO_WSGI_MODULE}:application \
  --name $NAME \
  --workers $NUM_WORKERS \
  --user=$USER --group=$GROUP \
  --log-level=debug \

Give Access to modify your user to modify files

sudo chown -R project_name:your_user /web/nginx/sites/
sudo chmod -R g+w /web/nginx/sites/

Give Execute permission To Gunicorn Start Script

sudo chmod u+x /web/nginx/sites/


Install Supervisor

sudo apt-get install supervisor

Create config

touch /etc/supervisor/conf.d/project_name.conf

In Project_Name.conf

command = /web/nginx/sites/   ; Command to start app
user = hello       ; User to run as
stdout_logfile =/web/nginx/sites/; Where to write log messages
redirect_stderr = true; Save stderr in the same log

sudo supervisorctl reread
sudo supervisorctl update

sudo supervisorctl status project_name          
sudo supervisorctl stop helproject_namelo  
sudo supervisorctl start project_name
sudo supervisorctl restart project_name


Install nginx :

sudo apt-get install nginx
sudo service nginx start

Configure Sites

Enable Site

sudo ln -s /etc/nginx/sites-available/project_name.conf /etc/nginx/sites-enabled/proejct_name.conf

Restart Nginx

sudo service nginx restart