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/site-a.com
      • /webapps/nginx/sites/site-b.com
    • apache
      • /webapps/apache/sites/site-a.com
      • /webapps/apache/sites/site-a.com
  • all python, nodejs other application will be on
    • /webapps/nginx/sites/site-a.com/application/app1
    • /webapps/nginx/sites/site-b.com/application/app2

Application Folder Structure

  • src
    • PROJECTX
      • PROJECTX
        • settings
          • base.py
          • settings_dist.py
          • settings .py
  • logs
    • nginx-error.log
    • nginx-access.log
    • gunicorn_supervisor.log
  • bin
    • activate
    • django-admin.py
    • 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/site-a.com/application/project_name project_name

Virtualenv

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.

django-admin.py startproject project_name

Gunicorn

 pip install gunicorn

wsgi

cd /web/nginx/sites/site-a.com/application/project_name/wsgi
touch app.wsgi

In app.wsgi

activate_this = '/web/nginx/sites/site-a.com/application/project_name/bin/activate_this.py'

execfile(activate_this, dict(__file__=activate_this))

import sys
sys.path.insert(0, '/web/nginx/sites/site-a.com/application/project_name/src')

from api import app as application

Test Gunicorn

cd /web/nginx/sites/site-a.com/application/project_name/wsgi

gunicorn app.wsgi:application --bind site-a.com:8001

Create Gunicron Start Script

cd /web/nginx/sites/site-a.com/application/project_name/bin
touch gunicorn_start

#!/bin/bash

NAME="project_name"                                  # Name of the application
DJANGODIR=/web/nginx/sites/site-a.com/application/project_name/src            # Django project directory
SOCKFILE=/web/nginx/sites/site-a.com/application/project_name/run/gunicorn.sock  # 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
cd $DJANGODIR
source ../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 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 \
  --bind=unix:$SOCKFILE

Give Access to modify your user to modify files

sudo chown -R project_name:your_user /web/nginx/sites/site-a.com/application/project_name/
sudo chmod -R g+w /web/nginx/sites/site-a.com/application/project_name/

Give Execute permission To Gunicorn Start Script

sudo chmod u+x /web/nginx/sites/site-a.com/application/project_name/bin/gunicorn_start

Supervisor

Install Supervisor

sudo apt-get install supervisor

Create config

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

In Project_Name.conf


[program:project_name]
command = /web/nginx/sites/site-a.com/application/project_name/bin/gunicorn_start   ; Command to start app
user = hello       ; User to run as
stdout_logfile =/web/nginx/sites/site-a.com/application/project_name/logs/gunicorn_supervisor.log; 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

Nginx

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