Step Seven: Configuring uWSGI and nginx

by Andy Boyle.

Now that we’ve set up the views and whatnot, it’s time to make the damn server work. This is probably the part that is the most difficult, in my opinion, as it’s the difference between a project being an idea on your laptop and being something that’s live and in the world.

After you read this, it may help to watch this presentation by Jacob Kaplan-Moss, one of the original creators of Django and an all-around coding badass. It explains deployment much better than I could, and while it’s super duper technical, it does go through some of what we’re doing here. It can’t hurt to learn more, right?

Anywho, if you remember in Step Two, we added a few directories, such as /opt/run/ and others. We’re using some of the basics that my pal Jeremy Bowers set up in his blog post on uWSGI and nginx.

What’s nginx and uWSGI, you ask? Nginx is, if you remember from my analogy in Step One, akin to the bartender getting you a beer. UWSGI would be more like if the bartender had to understand German in order to find the right beer. It acts sort of as a translator between your app and the server software.

Now, use your terminal and public key and ssh in to your instance. We will now get and install nginx and uWSGI. Do each line one at a time.

cd /opt/
wget http://projects.unbit.it/downloads/uwsgi-
wget http://nginx.org/download/nginx-0.8.51.tar.gz
tar -xzf nginx-0.8.51.tar.gz
tar -xzf uwsgi-

Woohoo. We have downloaded stuff. Aren’t we fancy? (Yes.) Now you need to compile and install uWSGI and nginx. It may look scary, but don’t worry. Enter each line one at a time, as per usual:

cd uwsgi-
cp uwsgi /usr/sbin

Not that hard, right? Now this bit’s a little harder. But don’t worry, you can just copy and paste stuff and it’ll all work out:

cd ../nginx-0.8.51/
touch /opt/run/nginx.pid
touch /opt/lock/nginx.lock
touch /opt/log/nginx/error.log

Now copy these lines and paste them into the terminal then hit enter:

./configure --conf-path=/etc/nginx/nginx.conf --error-log-path=/opt/log/nginx/error.log --pid-path=/opt/run/nginx.pid --lock-path=/opt/lock/nginx.lock --sbin-path=/usr/sbin\ --without-http-cache


make install

What did we just do? We told nginx where to look for its configuration file, we told it where to put its log file, and a bunch of other wonderfulness. Next we need to do some more fun configuration.


Go into your project directory, which should be at /opt/django-projects/firetracker/ and then we will make a few files:

mkdir uwsgi
touch uwsgi/__init__.py
touch uwsgi/wsgi_app.py

This is where Mr. Bowers would have you edit code in the terminal. But guess what? That always screws me up. So we’re just going to use FTP to edit that wsgi_app.py file. Go to the /opt/django-projects/firetracker/uwsgi/ directory and open the wsgi_app.py file using whatever FTP thing I told you to use (or whatever you’re using), and then paste this inside:

#! /usr/bin/env python
import sys, os, django.core.handlers.wsgi
os.environ['DJANGO_SETTINGS_MODULE'] = 'firetracker.settings'
application = django.core.handlers.wsgi.WSGIHandler()

Save that bad boy. Now we’re going to make a configuration file for this project that’ll help you control uWSGI. Do this:

cd /etc/init/
touch firetracker.conf

This file will allow you to quickly restart your app, using a simple command like “sudo service firetracker restart.” You’ll need to do that in the future if you ever change a view, model or admin file. So it’s good to have a shortcut. Now open up the file at /etc/init/firetracker.conf and throw this information inside:

description "uWSGI server for ProjectFiretracker"
start on runlevel [2345]stop on runlevel [!2345]
exec /usr/sbin/uwsgi
--socket /opt/run/firetracker.sock
--module wsgi_app
--pythonpath /opt/django-projects/firetracker/uwsgi -p 8

Jeremy’s post explains more about what this means. But hey, this is just meant to get you started. You can learn more about how the hell this all works later. Next thing you need to do is run this command to let the server know it has a new toy:

sudo initctl reload-configuration

And then do this to start your uWSGI instance:

sudo service firetracker start

You can also replace start with stop, or restart, and it’ll do what you think it should do. Just remember that any change you make to most of the core Django files, you’ll need to restart firetracker by ‘sudo service firetracker restart’ so it pops in the changes. Also remember that this needs to be running as well as nginx or else nothing will show up. Speaking of which, let’s set that up.


NOTE: Some pals have had errors with the nginx.conf later described in this tutorial. If you do, e-mail me at my website address at the email service Google happens to use.

The last thing we need to do is edit our nginx configuration file so it can talk to the uWSGI instance you just created. Using FTP, open up this file /etc/nginx/nginx.conf. Copy and paste this code inside and then save:

user www-data;
worker_processes 1;
error_log /opt/log/nginx.log;
pid /opt/run/nginx.pid;
events {
worker_connections 1024;
use epoll;
http {

include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
keepalive_timeout 65;
proxy_read_timeout 200;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
gzip on;
gzip_min_length 1000;
gzip_proxied any;
gzip_types text/plain text/css text/xml
application/x-javascript application/xml
application/atom+xml text/javascript;
proxy_next_upstream error;

server {
listen 80;
server_name your-long-ec2-instance-name-goes-here;
client_max_body_size 50M;
root /var/www/ht2;
location / {
uwsgi_pass unix://opt/run/firestarter.sock;
include uwsgi_params;

The only bit you should really notice is the the line that starts with server_name. After that you need to put your long EC2 name, which you can find in your AWS administrative panel on your EC2 page. Click on your running instance and then in the bottom window that pops up, look for “Public DNS.” This should look like ec2-123-123-123-123.compute-1.amazonaws.com or something. Copy that and paste it into the area after server name. And then take the numbers in the 123-123-123-123 — which is your IP address — and paste them after the instance public DNS (with a space in between).

Now run this:

sudo service nginx start

And voila! You have uWSGI and nginx running, listening on port 80. You won’t need to “sudo service nginx restart” unless you change something in the .conf file, which you won’t need to do unless you add another project in the future. Don’t worry about that for now.

Go to It should spit out some basic information. But nothing will load because you have no data entered! We will do that in the next post. Now let’s move on to Step Eight, which sets up the admin.