Fun with Django and modwsgi
Today I deployed my first Django application for a client. Its yet-another-blog, so I’ll refrain from posting the code and cluttering up the django-*blog* namespace on Google Code. Before you roll your eyes and complain about why I didn’t use an existing solution, I think I have 2 somewhat valid reasons:
- The client actually needed a subset of the features most blogs offer, so I wouldn’t really have anything to contribute back to an existing project.
- Blogs are one of the simplest content driven web applications in existence. Wikis are just a bit simpler perhaps. At any rate, creating a blog app is an excellent way to learn a framework.
Python Deployment Decisions
In the past I’ve used CherryPy as my framework and a simple mod_proxy configuration to run the applications behind Apache. Django considers its built-in web server a development tool only, so I figured it was time to explore the myriad of Python web app deployment alternatives: mod_python, FastCGI, modwsgi. I’m sure there are many more, but I’d say those are the big 3.
I had tried to deploy Python web applications on DreamHost using FastCGI before and entered the hell that is deploying Python web apps on shared hosts. So FastCGI wasn’t my first choice this time.
I had also tried mod_python for deploying CherryPy apps on my Linode before and for whatever reason just found mod_proxy to be much easier to setup and manage.
I was kind of eager to try out modwsgi because its been getting a lot of attention lately, so I downloaded the source and compiled it on my Debian Etch server.
Deploying a Django App via modwsgi
modwsgi was quite easy to setup as long as you follow the instructions in their wiki for Django integration. I was hit by bug #3762, but the modwsgi documentation got me through it. (For what its worth the attached wsgi.patch also worked, but I don’t really want to run a patched version of Django.)
One big problem I ran into was sqlite3 gave me OperationalError: unable to open database file whenever I did anything that would write to the database. My database file was owned by www-data (the Apache process owner) and had the permissions 664.
I switched to PostgreSQL, ran syncdb, and everything worked beautifully.
My wsgi script file /srv/spam/eggs/eggs.wsgi:
import os, sys sys.path.append('/srv/spam') sys.path.append('/srv/spam/eggs') os.environ['DJANGO_SETTINGS_MODULE'] = 'eggs.wsgi_settings' import django.core.handlers.wsgi _application = django.core.handlers.wsgi.WSGIHandler() def application(environ, start_response): environ['PATH_INFO'] = environ['SCRIPT_NAME'] + environ['PATH_INFO'] return _application(environ, start_response)
Note I use wsgi_settings instead of my usual settings file. wsgi_settings just imports my main settings file and changes some to their production values.
My Django application actually drops into the /blog/ and /accounts/ folders under a VirtualHost otherwise occupied by static files and some PHP scripts. modwsgi made this easy by putting this in my existing VirtualHost:
WSGIScriptAliasMatch /(blog|accounts)/.* /srv/spam/eggs/eggs.wsgi # A simple Alias directive handles my static files Alias /static/ /srv/spam/eggs/static/
Bottom Line
I highly recommend using modwsgi for deploying Python web applications. sqlite3 may work for you. In my case its probably best I use PostgreSQL for a number of reasons.
Tags: apache, cherrypy, diy, django, dreamhost, fastcgi, modwsgi, mod_python, Python, wsgi
February 5th, 2008 at 11:38 pm
[...] Dexternights|Dexter|Mobile reviews|Tech Guide|Tech Blogs|Indian IT|Software Blog|Dinesh wrote an interesting post today onHere’s a quick excerpt [...]
February 6th, 2008 at 5:24 am
With SQLite, it’s not just the database file that needs to be writeable by the web server process, but the directory it’s in as well — so the SQLite engine can create temporary files. This is a really common gotcha.
In any case, congrats. And mod_wsgi is indeed nice.
February 6th, 2008 at 5:49 pm
Have you noticed a speed increase since switching to mod_wsgi ? or is it just easier to setup?
August 19th, 2008 at 8:01 pm
Your links after ‘deployment alternatives’ are all broken
August 19th, 2008 at 8:28 pm
@Walter: Thanks for the heads up. Fixed them.