My uWSGI-Nginx-Django Configuration

  • Tue 09 October 2012

  • I'm writing this as a result of finding numerous how-to's that in my experience, did not work. What exists below, does work, in fact, is serving public/production sites right now.

    I'm not saying this is the only way to make this work, I'm just saying this is the only way I could get it to work.

    Here is what my "stack" looks like:

    • Ubuntu 12.04 LTS
    • Nginx 1.2.3
    • uWSGI 1.3.0
    • Django 1.4.1

    I'm using Nginx from Ubuntu's repository but I'm installing uWSGI via PIP (globally!! -- not in my virtualenv).

    Try this on for size:

    sudo apt-get install nginx sqlite3
    pip install uwsgi
    

    I'm not aware of any need or incentive to run a version of Nginx >1.2.3 (or what exists in Ubuntu 12.04's repository. The sqlite3 package is a dependancy of uWSGI.

    WTF am I doing installing uWSGI via pip??!!

    1. I needed uWSGI ver >= 1.2.6 because I'm using New Relic
    2. uWSGI docs say to

    With the packages and dependancies out of the way, here are the necessary configuration files:

    My /etc/init/uwsgi.conf file.

    description "uWSGI"
    start on runlevel [2345]
    stop on runlevel [06]
    respawn
    
    env UWSGI=/path/to/executable/uwsgi
    env LOGTO=/var/log/uwsgi/emperor.log
    
    exec $UWSGI --master --emperor /etc/uwsgi/apps-enabled --die-on-term --uid
    www-data --gid www-data --chmod-socket --logto $LOGTO
    

    I guess the "secret sauce" that exists here is --master and --emperor. You can read about Emperor mode via uWSGI's docs.

    In order to serve the app via uWSGI, you need to define an .ini file (other file types supported).

    My /etc/uwsgi/apps-available/project.ini file -- note, this gets symlinked to /etc/uwsgi/apps-enabled/project.ini

    [uwsgi]
    base = /usr/share/nginx/tc2012
    home = /usr/share/nginx/tc2012/venv
    pythonpath = %(base)
    socket = /tmp/%n.sock
    module = web_site.wsgi
    logto = /var/log/uwsgi/%n.log
    

    A few things to take note in project.ini:

    • base is your base project directory, NOT your Django app directory.
    • home is the path to your virtualenv.
    • module is the location of your wsgi file (by default, this is in base-project/django-project/wsgi.py).
    • You'll also notice that I'm pointing to a socket, you can also define a port.

    Below is my project.conf file for Nginx.

    server {
    
        server_name localhost;
    
        location /site_media/static {
        expires max;
        alias /path/to/www-root/project/django_project/static;
        }
    
        location /site_media/media {
        expires max;
        alias /path/to/www-root/project/django_project/site_media/media;
        }
    
        location / {
        include        /etc/nginx/uwsgi_params;
        uwsgi_pass     unix:/tmp/project.sock;
        }
    
        }
    

    My /etc/nginx/sites-available/project.conf file -- note, this gets symlinked to /etc/nginx/sites-enabled/project.conf.

    The two things regarding uWSGI and Nginx to take away from this is include /etc/nginx/uwsgi_params; and uwsgi_pass unix:/tmp/project.sock; where project.sock is the name of the .sock file referenced in your project.ini file above.

    That's pretty much it! If something isn't quite clear or perhaps a typo/fat-finger, please let me know in the comments.

    Comments !

    social