Deploy Django Applications Using uWSGI and Nginx on Ubuntu 14.04

Updated by Sergey Pariev Contributed by Sergey Pariev

Contribute on GitHub

View Project | View File | Edit File

This is a Linode Community guide. Write for us and earn $250 per published guide.


Django is a high-level Python Web framework that encourages rapid development and clean, pragmatic design. This guide provides an introduction to deploying Django applications using uWSGI and nginx on Ubuntu 14.04.

Before You Begin

  1. Familiarize yourself with our Getting Started guide and complete the steps for setting your Linode’s hostname and timezone.

  2. This guide will use an example account named django. Complete the sections of our Securing Your Server guide to create the django user, harden SSH access and remove unnecessary network services. You may need to create additional firewall rules for your specific application.

  3. Update your system:

    1
    sudo apt-get update && sudo apt-get upgrade
    

This guide is written for a non-root user. Commands that require elevated privileges are prefixed with sudo. If you’re not familiar with the sudo command, you can check our Users and Groups guide.

Install nginx, Python Tools and uWSGI

  1. Install the system packages required for nginx, the SQLite Python bindings, and managing Python Tools:

    1
    sudo apt-get install build-essential nginx python-dev python-pip python-sqlite sqlite
    

    If your application uses another database, skip installing python-sqlite and sqlite.

  2. Install virtualenv and virtualenvwrapper:

    1
    sudo pip install virtualenv virtualenvwrapper
    

    virtualenv and virtualenvwrapper are tools to create isolated Python environments. They help better manage application dependencies, versions and permissions. For virtualenvwrapper to function correctly, run the following commands:

    1
    2
    echo "export WORKON_HOME=~/Env" >> ~/.bashrc
    echo "source /usr/local/bin/virtualenvwrapper.sh" >> ~/.bashrc
    
  3. Activate virtualenvwrapper in the current session:

    1
    source ~/.bashrc
    
  4. Install uWSGI using pip:

    1
    sudo pip install uwsgi
    

Set up a Sample Django Application

  1. Be sure that you’re in the django user’s home directory and create the virtual environment for the application:

    1
    cd /home/django && mkvirtualenv sample
    

    After executing this command your prompt will change to something like (sample)django@example.com:~$ indicating that you are using the sample virtual environment. To quit the virtual environment, enter deactivate.

  2. Install the Django framework:

    1
    pip install Django
    
  3. Create the new Django application sample, located at /home/django/sample:

    1
    django-admin.py startproject sample
    
  4. Switch to the Django application’s directory and initialize SQLite database:

    1
    cd ~/sample && ./manage.py migrate
    
  5. When running Django with nginx, it’s necessary to configure Django to put all static assets in your application’s static folder. Specify its location in settings.py:

    1
    echo 'STATIC_ROOT = os.path.join(BASE_DIR, "static/")' >> sample/settings.py
    
  6. Run the following command to move all static assets into the directory mentioned above:

    1
    ./manage.py collectstatic
    
  7. Start a development server to test the sample application:

    1
    ./manage.py runserver 0.0.0.0:8080
    

    Visit http://example.com:8080 in your browser to confirm that the sample application is set up correctly and working. You should see the Django test page:

    Django test page.

    Then stop development server with Ctrl-C.

Configure uWSGI

  1. Create a directory with uWSGI configuration files:

    1
    sudo mkdir -p /etc/uwsgi/sites
    
  2. Create configuration file sample.ini with the following contents:

    /etc/uwsgi/sites/sample.ini
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    [uwsgi]
    project = sample
    base = /home/django
    
    chdir = %(base)/%(project)
    home = %(base)/Env/%(project)
    module = %(project).wsgi:application
    
    master = true
    processes = 2
    
    socket = %(base)/%(project)/%(project).sock
    chmod-socket = 664
    vacuum = true
    
  3. Create an Upstart job for uWSGI:

    /etc/init/uwsgi.conf
    1
    2
    3
    4
    5
    6
    7
    8
    9
    description "uWSGI"
    start on runlevel [2345]
    stop on runlevel [06]
    respawn
    
    env UWSGI=/usr/local/bin/uwsgi
    env LOGTO=/var/log/uwsgi.log
    
    exec $UWSGI --master --emperor /etc/uwsgi/sites --die-on-term --uid django --gid www-data --logto $LOGTO
    

    This job will start uWSGI in Emperor mode, meaning that it will monitor /etc/uwsgi/sites directory and will spawn instances (vassals) for each configuration file it finds. Whenever a config file is changed, the emperor will automatically restart its vassals.

  4. Start the uwsgi service:

    1
    sudo service uwsgi start
    

Configure nginx

  1. Remove the default nginx site configuration:

    1
    sudo rm /etc/nginx/sites-enabled/default
    
  2. Create an nginx site configuration file for your Django application:

    /etc/nginx/sites-available/sample
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    server {
        listen 80;
        server_name example.com;
    
        location = /favicon.ico { access_log off; log_not_found off; }
        location /static/ {
            root /home/django/sample;
        }
    
        location / {
            include         uwsgi_params;
            uwsgi_pass      unix:/home/django/sample/sample.sock;
        }
    }
    
  3. Create a symlink to nginx’s sites-enabled directory to enable your site configuration file:

    1
    sudo ln -s /etc/nginx/sites-available/sample /etc/nginx/sites-enabled
    
  4. Check nginx’s configuration and restart it:

    1
    sudo service nginx configtest && sudo service nginx restart
    
  5. You should now be able to reach your Django application by visiting your Linode’s hostname or IP address on port 80 in your browser.

More Information

You may wish to consult the following resources for additional information on this topic. While these are provided in the hope that they will be useful, please note that we cannot vouch for the accuracy or timeliness of externally hosted materials.

This guide is published under a CC BY-ND 4.0 license.