Ubuntu Hardy - Using mod_wsgi to Serve Your Application

If you've followed the previous article you should have Apache and mod_wsgi ready to serve an app for you.

In this article we'll create a basic Django app and setup the virtual host that will allow Apache and mod_wsgi to work their magic.

Create the Django Application

First thing's first, move to your home directory and go into your public_html/domain1.com folder (if you don't have one, create one and of course give it the name of your domain rather than domain1.com):

cd ~/public_html/domain1.com

Next you'll want to create a Django project which is done with the django-admin.py tool:

django-admin.py startproject testproject

Create the Virtual Host and WSGI file

For Apache to be able to actually serve a Django application it needs to know that it should hand off certain requests to mod_wsgi. We also need to create a WSGI file to tell mod_wsgi how to handle our requests. To accomplish this, we'll setup a virtual host that tells Apache where our WSGI file is and then setup the WSGI file accordingly.

This example is very basic but it will get you going:

sudo nano /etc/apache2/sites-available/domain1.com

Then type or copy the following virtual host definition:

<VirtualHost *:80>
        ServerName domain1.com
        ServerAlias www.domain1.com
        WSGIScriptAlias / /home/demo/public_html/domain1.com/testproject.wsgi

This tells Apache to pass any request it receives to mod_wsgi and to use the WSGI file we specified earlier. Now to create the WSGI file:

nano /home/demo/public_html/domain1.com/testproject.wsgi

Then add the following WSGI definition:

import os
import sys


os.environ['DJANGO_SETTINGS_MODULE'] = 'testproject.settings'

import django.core.handlers.wsgi

application = django.core.handlers.wsgi.WSGIHandler()

This will take care of importing the necessary modules, append our Django project path to the Python path and set a few variables to help mod_wsgi do its job. Once completed, you'll need to enable the virtual host and reload Apache:

sudo a2ensite domain1.com
sudo /etc/init.d/apache2 reload

Providing everything went as expected you should be able to visit your domain (or slice IP) in your browser and get your newly created Django application. It should look something like this:

Welcome to Django

Note: If you get any port and NameVirtualHost errors upon reloading Apache, please ensure you read the Apache Virtual Hosts article.

Static Content

As the astute of you may have noticed, there is one caveat to the virtual host definition provided in that it does not allow the serving of static content.

That is to say, no document root was specified and there is nothing to indicate that static files are not to be handled by mod_wsgi and Django.

The Django team actually recommends you use a secondary web server to serve static content, however, you can make a few tweaks in your testproject/settings.py file and use the following virtual host definition:

<VirtualHost *:80>
        ServerName domain1.com
        ServerAlias www.domain1.com
        WSGIScriptAlias / /home/demo/public_html/domain1.com/testproject.wsgi

        Alias /static/ /home/demo/public_html/domain1.com/static/
        <Location "/static/">
            Options -Indexes

The Alias directive tells Apache to not let Django/mod_wsgi handle anything that's located under /static/ on your site. You can set this to be anything you like, but you'll need to make the appropriate directory available under /home/demo/public_html/domain1.com. In this example the directory would be called "static".

Tweaks for the settings.py file involve setting the MEDIA_URL and MEDIA_ROOT settings appropriately:

nano /home/demo/public_html/domain1.com/testproject/settings.py

Find the following two settings and edit them like so:

MEDIA_ROOT = '/home/demo/public_html/domain1.com/static/'
MEDIA_URL = '/static/'

Restart Apache now to make the updates take effect:

sudo /etc/init.d/apache2 reload

Now any items placed in /home/demo/public_html/domain1.com/static can be accessed via http://domain1.com/static/path/to/file.

Changes to your Django Application

When you update your python code or templates in a Django application with mod_wsgi, you'll usually need to give Apache a reload to see the changes. So it's good to get into the habit of reloading Apache after making any changes to your project.

At this point you should now be able to successfully build out a Django application and have mod_wsgi as well as Apache serve it up for you.

Ben H.

Article Comments:

Alanna commented Sun Sep 06 16:43:01 UTC 2009:

Thank you! I've been biting my nails for this sequel. :)

victor commented Sat Mar 06 21:46:24 UTC 2010:

I followed these instructions... no error occurred... I still can't see my Django start page.... what should I do? I've read tutorials on setting Django on Slicehost.. still nothing!

Andrew commented Sun May 09 21:18:05 UTC 2010:

I had to use:

sudo a2dissite default

and restart to disable the default site, before the django page showed up.

django developers commented Thu Sep 02 03:43:40 UTC 2010:

Thanks for the article. I absolutely hate having to use SSH and Linux, although I love the fact that Linux exists :)

kdude commented Wed Mar 02 10:54:28 UTC 2011:

Worked! I can see my Django default project page. Good tutorial. Short and to the point. Before this, I was trying nginx with Gunicorn, Apache2 with Nginx, uWGSI. Had to clean my machine and start again.

Want to comment?

(not made public)


(use plain text or Markdown syntax)