iA


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-0.9.6.4.tar.gz
wget http://nginx.org/download/nginx-0.8.51.tar.gz
tar -xzf nginx-0.8.51.tar.gz
tar -xzf uwsgi-0.9.6.4.tar.gz

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-0.9.6.4
make
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

Now:

make
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.

SETTING UP UWSGI

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
sys.path.append('/opt/django-projects/')
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]
respawn
exec /usr/sbin/uwsgi
--socket /opt/run/firetracker.sock
--chmod-socket
--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.

SETTING UP NGINX

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 123.123.123.123;
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 123.123.123.123/firetracker/ 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.

8 comments on ‘Step Seven: Configuring uWSGI and nginx’

  1. Chris Keller says:

    I am happy to say I made it this far today… But going to /firetracker leaves me spinning… Fantastic write up and I can’t tell you how much I learned by walking through this… Just the info about AWS is gold. Thank you.

  2. Andy Boyle says:

    Hey Chris,

    Turns out there may be a few errors in my nginx.conf set up. I discovered it when walking through this on my own. I’ll be making some changes hopefully in the next few days and I’ll let you know when it’s done. Glad the walkthrough was helpful!

  3. Kevin Schaul says:

    Andy/Chris-

    Did this ever get updated? I’m running into problems starting nginx, it says it’s failing the test from the .conf file.. any ideas?

    Also, great stuff here. Tons of help. Thanks!

  4. Andy Boyle says:

    Dammit. I guess I should go back in and actually fix this, eh?

    I will look at this tonight as a few friends have been having this issue. I’ll see what I can do.

  5. Kevin Schaul says:

    Well, one issue I found is the .conf file says:
    respawnexec /usr/sbin/ …

    But it should be:
    respawn
    exec /usr/sbin/ …

    Which almost gets it working for me, except now I’m getting a 111 connection refused error on my .sock when I try to load a page. I’ll post if I figure out anything more.

  6. Chris Essig says:

    Awesome tutorial! I can’t tell you how much I’ve learned. But I’ve got one issue. When I run:
    - sudo service firetracker start
    I get:
    - start: Unknown job: firetracker

    I noticed someone on Google + was having the same issue and wasn’t sure if you found a solution. I’ve gone back and triple checked everything…The only thing different is I’m using nginx-1.0.10 not nginx-0.8.51 because I was having issues with the older version.

    So far I haven’t had any issues setting up nginx…I can’t get the web page to load but I figure that has something to do with it not recognizing the firetracker job.

    Thanks in advance!

  7. Tom Meagher says:

    I’m having two problems with this. First, I get error message when trying to start uWSGI:
    start: Unknown job: uwsgi_firetracker

    I went ahead and set up the nginx conf, but had another problem, which I think Kevin hit as well.
    “Starting nginx: [emerg]: unknown directive “uwsgi_pass” in /etc/nginx/nginx.conf:33
    configuration file /etc/nginx/nginx.conf test failed”

    Any advice?

    Thanks, Tom

  8. John Henry says:

    Awesome tutorial! I am able to follow every step but this one:
    initctl reload-configuration

    What do I do now? (Running Django on a shared hosting acct)

Leave a Reply