How to Host Multiple Django or Python Apps on the Same Host With Nginx and Gunicorn

By | 2014/04/03

It is possible to run multiple Django apps or Python apps on a single host by specifying unique ports for each app in Gunicorn and Nginx. Here are some tips!


This example uses nginx and gunicorn on Debian Wheezy from the Debian repositories.

Install nginx and gunicorn from apt-get:

$ sudo apt-get install nginx gunicorn

First, create individual nginx site files for each site under /etc/nginx/sites-available/

In nginx, server_name is what will connect your browser to the right app or site that is being hosted. Also note that you must use a unique port number on the proxy_pass line for each django site or python app running on the host.

/etc/nginx/sites-available/example.com

server {
    listen 80;
    server_name example.com;
    access_log  /var/log/nginx/access.log;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

}


/etc/nginx/sites-available/example2.com

server {
    listen 80;
    server_name example2.com;
    access_log  /var/log/nginx/access.log;

    location / {
        proxy_pass http://127.0.0.1:8001;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

}

To enable these sites for nginx, create a symlink to /etc/nginx/sites-enabled/ for each site.

$ sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com

Next, make a gunicorn config file for each site under /etc/gunicorn.d/ on Debian. Make sure the file ends with .conf. Note that the port number must match to the port number specified in your nginx config for each site.

Note: for these I have a file /var/www/example.com/wsgi-app.py as my wsgi script.

/etc/gunicorn.d/example.com.conf

CONFIG = {
    'mode': 'wsgi',
    'working_dir': '/var/www/example.com',
      'python': '/var/www/example.com/virtualenv/bin/python',
    'args': (
        '--bind=127.0.0.1:8000',
        '--workers=4',
        '--timeout=260',
        '--max-requests=500',
        'wsgi-app',
    ),
}


/etc/gunicorn.d/example2.com.conf

CONFIG = {
    'mode': 'wsgi',
    'working_dir': '/var/www/example2.com',
      'python': '/var/www/example2.com/virtualenv/bin/python',
    'args': (
        '--bind=127.0.0.1:8001',
        '--workers=4',
        '--timeout=260',
        '--max-requests=500',
        'wsgi-app',
    ),
}

When ready, start gunicorn, then nginx.

$ sudo /etc/init.d/gunicorn start

$ sudo /etc/init.d/nginx start

Host additional sites by using additional port numbers!

Problems? To get debugging info from gunicorn, consider temporarily enabling debug logging. On Debian, gunicorn logs to /var/log/gunicorn/ .

CONFIG = {
    'mode': 'wsgi',
    'working_dir': '/var/www/example.com',
      'python': '/var/www/example.com/virtualenv/bin/python',
    'args': (
        '--bind=127.0.0.1:8000',
        '--workers=4',
        '--timeout=260',
        '--max-requests=500',
        'wsgi-app',
        '--debug',
        '--log-level=debug',
    ),
}