I recently deployed a Django web app built on Pinax. I had heard a lot of good things about mod_wsgi as opposed to mod_python, so I wanted to give it a shot. This was my first time using mod_wsgi and when I tried following the steps in the Pinax documentation, all I got was server 500 errors. What should have probably only been a 10 minute procedure turned into an hour of cursing and fist shaking, and it seems like I’m not the only one who had problems getting WSGI to play nice with Pinax. To spare you the same fate I thought I would write up the correct way to deploy a Pinax project with mod_wsgi.
NOTE: The official documentation and files may have been changed after originally writing this. I’m currently using Pinax 0.5.1 with Django 1.0.2. This project was deployed on a Webfaction shared host (highly recommended for hosting Django projects!) but I don’t think it really matters what host you use.
Short version
If you already know how to use mod_wsgi, the short version of why following the steps in the Pinax documentation doesn’t work is that it sets up your sys.path incorrectly. Pinax uses a lot of external apps and libraries which need to be included.
If you’re brand new to mod_wsgi though, read on.
Set up
I’ll run through deploying the complete_project that comes with the default installation of Pinax 0.5.1. I’ll assume that pinax lives in PATH/pinax/, and that you already have your database set up and installed. To get this to work with your project, just change the following instances of PATH to the absolute path Pinax sits on, and change complete_project to the name of your project.
Settings.py
Add the following to your Settings.py file
from os.path import abspath, join, dirname
PINAX_ROOT = abspath(join(dirname(__file__), "../../"))
PROJECT_ROOT = abspath(dirname(__file__))
This assumes that you’re using the default directory structure that comes with Pinax 0.5.1. If you’re using something different, just change PINAX_ROOT to PATH/pinax/ and PROJECT_ROOT to the absolute path of your project.
wsgi_handler.py
You will need a script to create a WSGI-handler for your project, which we’ll call wsgi_handler.py. It’s recommended for security reasons that you keep your WSGI script in a directory separate from your website, and not in the DocumentRoot for your Apache installation. Create a directory called ‘wgsi’ at PATH/wgsi/ and place wsgi_handler.py in it, so you have something like this:
PATH/wsgi/wsgi_handler.py
If you use a revision control sysem like SVN and want to keep wsgi_handler.py in SVN, just create a symbolic link in PATH/wsgi/ that links to wherever you want to keep wsgi_handler.py.
In wsgi_handler.py put
import sys
from os.path import abspath, dirname, join
from os import environ
from site import addsitedir
# redirect sys.stdout to sys.stderr for libraries that use
# print statements for optional import exceptions.
sys.stdout = sys.stderr
sys.path.insert(0, abspath(join(dirname(__file__), "../pinax/projects")))
from django.conf import settings
environ['DJANGO_SETTINGS_MODULE'] = 'complete_project.settings'
path = addsitedir(join(settings.PINAX_ROOT, "libs/external_libs"), set())
if path:
sys.path = list(path) + sys.path
sys.path.insert(0, join(settings.PINAX_ROOT, "apps/external_apps"))
sys.path.insert(0, join(settings.PINAX_ROOT, "apps/local_apps"))
sys.path.insert(0, join(settings.PROJECT_ROOT, "apps"))
sys.path.insert(0, settings.PROJECT_ROOT)
from django.core.handlers.wsgi import WSGIHandler
application = WSGIHandler()
http.conf
Edit your Apache http.conf to make sure mod_wsgi and mod_authz_host are loaded:
LoadModule wsgi_module modules/mod_wsgi.so
LoadModule authz_host_module modules/mod_authz_host.so
The actual path to the modules may be different on your system, so make sure those are correct. Then add the following code:
WSGIScriptAlias / PATH/wsgi/wsgi_handler.py
WSGIDaemonProcess complete_project processes=1 threads=10
WSGIProcessGroup complete_project
<Directory PATH/wsgi>
Order allow,deny
Allow from all
</Directory>
Edit the WSGIDaemonProcess line to control the amount of system resources you want mod_wsgi to use. For small to medium load websites, I’ve heard that 1 process with 10 threads should be ok.
(psstt, don’t forget to configure apache to serve your static files and not Django!)
And that’s it! Restart apache and hopefully your Pinax project is up and running. Drop me a note in the comments or shoot me an email at david.ziegler {at} gmail.com if I’m wrong or missed something.
More info and tutorials on mod_wsgi, Django, and Pinax:
http://code.google.com/p/modwsgi/wiki/QuickConfigurationGuide
http://www.technobabble.dk/2008/aug/25/django-mod-wsgi-perfect-match/
http://www.20seven.org/journal/2008/09/pinax-setup-and-deploy.html