How to setup Django + mod_wsgi on Apache & Ubuntu

Django is a great Web Framework which complements the Python programming language. Having switched to Python development few months ago I was on the lookout for a MVC like Web Framework that emphasizes Convention over Configuration (CoC), Rapid Development Principle of Don’t Repeat Yourself (DRY), Separation of concerns has Python as the underlying core language. And lo and behold Django proved to be that beast.

What is Django

Django is a MVT (model-view-template) framework build on the Python language. The MVT is identical to MVC (model-view-controller) but where in the common MVC pattern the view here is the template and controller the view. They both perform the same function separating the business logic from the presentation from the data layer (model). However Django does goes one step further and provides a view/template without native core language polluting the HTML.

Django emphasizes Reusability and “Pluggability” of components, Rapid Development, and the Principle of DRY (Don’t Repeat Yourself). Stuff you hear a lot with Ruby on Rails – another great web framework built on a solid language, Ruby.

Ok, enough of my rambling about how great this framework is. If you want to read more about it I recommend the following 2 links:

The LAMP stack

Ok so everyone is talking about a LAMP stack and everyone wants to run their site on a LAMP stack. Why not when you can tap into great open source tools for free. The word LAMP is a bit over emphasised since most sites today run on a custom configured implementation using best of breed open source software.

“LAMP is an acronym for a solution stack of free, open source software, referring to the first letters of Linux (operating system), Apache HTTP Server, MySQL (database software) and PHP (or sometimes Perl or Python), principal components to build a viable general purpose web server” ~ Wikipedia

Few years ago when open source software was limited, LAMP had typically meant Linux, Apache, MySQL and PHP. Today Linux can take many flavours from CentOS, Red Hat or the popular Debian-derived Linux distribution Ubuntu. The web server Apache can be replaced with a super fast & lighter HTTP and reverse proxy server called nginx. MySQL, post Oracle acquisition is often replaced with PostgreSQL or a NoSQL version called MongoDB. And PHP by cleaner & concise languages like Python or Ruby.

In this post I will cover how to setup a LAMP stack where:

  • Linux = Ubuntu 11.10. This can also work with 10.xx version of Ubuntu.
  • Apache = we will leave it as is since it is still a great web server but hook in mod_wsgi – a Python WSGI adapter module for Apache. WSGI is nothing more than an interface specification by which server and application communicate. In this case with Python.
  • MySQL = will stay with MySQL but you can also install MongoDB.
  • PHP = will be replaced with Python and drop in the Django MVT framework.

Ok let’s get started.

How to Setup Django on Ubuntu

The following assumes you have already installed Ubuntu and LAMP. If not head over to my prior posts on how to:

  1. Install Ubuntu on EC2 and
  2. Install LAMP.

Installing pre-req components

1. Standard procedure is to always run update on your Ubuntu installation.

sudo apt-get update

2. Install mod_wsgi on Apache

sudo apt-get install libapache2-mod-wsgi

3. Install Python setup tools with pip. pip installs packages. Python packages. An easy_install replacement.

sudo apt-get install python-setuptools
sudo apt-get install python-pip

4. Install Django MVT framework using pip.

sudo pip install Django

Now that’s done. Easy hey. Now let’s configure your 1st Django site.
Assuming your site will be called “

Configuring your 1st Django site

5. Recall from the LAMP setup that we were storing all web sites in /var/www/ folder. For example purposes, I will use purpleblue_com as my Django project. Notice the use of to create the Django site and the use of underscores vs decimal point. Only numbers, letters and underscores are allowed in the Django project name.

cd /var/www/
sudo startproject purpleblue_com

5.1 Verify new project by typing this in and hitting enter. ls lists the contents of a directory showing all files inc hidden ones, hence the -all option.

ls –all

If you see purpleblue_com listed, then change directory to it.

cd purpleblue_com

and verify you can see 4 .py files – init, manage, settings & urls. Those are Django new project default install files.

6. Now we create a wsgi file for the site so apache knows how to run this site.

sudo mkdir /var/www/purpleblue_com/apache
sudo nano /var/www/purpleblue_com/apache/django.wsgi

… and add this into django.wsgi

import os
import sys

path = '/var/www/purpleblue_com'
if path not in sys.path:
    sys.path.insert(0, '/var/www/purpleblue_com')

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

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

TIP: It’s always a good idea to specify the actual application module.

6. Using webmin (ref our LAMP install) setup new apache site for this project.

6.1 Go to: https://YOUR_DEV_VM_IP:10000/
6.2 Servers > Apache Webserver > Create virtual host
6.3 Configure your new host
Document Root = /var/www/purpleblue_com/
Server Name =
6.4 Click on “Create Now” button. And go back into the settings by clicking on “Virtual Server” button next to your new host.
6.4 Click on “Edit Directives” and paste the following in:

DocumentRoot /var/www/purpleblue_com

<Directory /var/www/purpleblue_com>
    Order allow,deny
    Allow from all

WSGIDaemonProcess purpleblue_com processes=2 threads=15 display-name=%{GROUP}
WSGIProcessGroup purpleblue_com

WSGIScriptAlias / /var/www/purpleblue_com/apache/django.wsgi

The last 3 lines above allow this Django site to run in daemon mode.

TIP: When you make any .py changes in your Django site, rather then restarting/refreshing apache you can touch this wsgi and the changes will be picked up.

sudo touch /var/www/purpleblue_com/apache/django.wsgi

7. Restart apache to take new site & settings into effect.

sudo /etc/init.d/apache2 restart

8. Add the new domain to your primary OS host file pointing to your VM where the Django project purpleblue_com resides.

9. Test your new project by going to the Server Name ( you just setup. You should see a similar default Django installation page:

It worked! Congratulations on your first Django-powered page.

If you get an error or cannot see the default Django installation page make sure you check out apache log file. Common approach is to grab the tail end of the apache error log file to see what just happened.

tail /var/log/apache2/error.log

Bonus – Django CMS

If you have the time also check out Django CMS that is built on top of the Django Web Framework.

Django CMS site:

Happy Django exploring & Python coding!


The following two tabs change content below.
  • GG

    Great stuff, I found this very useful.  The only issue I had was that:

    Order allow,deny
    Allow from all
    did not work for me – there are too many spaces in the markup tags. They should read:
    Order allow,deny
    Allow from all
    but other than that, this was an incredibly useful guide – thanks a lot for producing it.

    • Ernest Semerda

      Hey thanks for the feedback GG! It’s always nice to hear that stuff like this is helping folks.

      Yeah I should have put in a note earlier (I did now) to tell folks to remove the additional spaces around “Directory” in step 6.4. Without those spaces WordPress parsed it as code and wouldn’t display it in the post. Thanks again!!

  • Mike

    My web server (linode) dosen’t allow me to use webadmin, can you show what the appache2.conf should look like?

    • Mike

      was able to get in using firefox, damn you chrome!

  • Mike

    Ok now I have a real question, in this set up, how do you get css to work from the same box? I’m getting 404 errors.

    • Ernest Semerda

      Hey sorry I missed your question. Did you get it all working as expected?

  • Pingback: Gentle Introduction to Python - The Road to Silicon Valley()

  • Андрей Сирота

    In .wsgi – file need rewrite:
    import os

    import sys

    path = ‘/var/www/purpleblue_com’

    if path not in sys.path:

    sys.path.insert(0, ‘/var/www/purpleblue_com’)

    os.environ[‘DJANGO_SETTINGS_MODULE’] = ‘purpleblue_com.settings’

    import django.core.handlers.wsgi

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


    and in .conf file of virtual host too many spaces in tags.

    thanks for nice tutorial ^_^

    • Ernest Semerda

      Awesome catch. Thank you :-) Changes have been made. Re the .conf file spacing this was intentional since the previous version of wordpress wanted to parse it as markup.

  • gamesbook

    Hi. Can you explain Step 8 in a bit more detail:

    “8. Add the new domain to your primary OS host file
    pointing to your VM where the Django project purpleblue_com resides.”

    What VM are you referring to? Its not mentioned anywhere else. Also can “” just be a name that is made up (not connected with anything else in any way)? So “” or some such nonsense?

    • Ernest Semerda

      The VM / the machine you just setup.
      Yes is just a hostname which you can make up.