Reusable solution for deploying Django in Apache

Django plays with Apache very well. Using mod_wsgi is recommended
to host Django apps in Apache and by my (short) experience it works fine.
There are few things I did not like on all the deployment docs/manuals
and it was the way how they handle the paths to application.
I was OK with entering fixed, absolute path to my django app in host config of Apache, but it made no sense for me to insert the path to application in django.wsgi or settings.py files.
Here is the solution which worked fine.
Configuration of VirtualHost in Apache:

<VirtualHost *>
ServerName www.mysite.com
WSGIDaemonProcess mysite processes=2 maximum-requests=500 threads=1
WSGIProcessGroup mysite
WSGIScriptAlias / /var/www/mysite/django.wsgi
Alias /site-media "/var/www/mysite/site-media"
Alias /admin-media /usr/lib/python2.6/site-packages/django/contrib/admin/media
<Directory /var/www/mysite>
    Order deny,allow
    Allow from all
</Directory>
</VirtualHost>

This is the only place you need to set fixed path to django app.
As you can see, WSGIScriptAlias directive points to django.wsgi file in project directory,
which does handle requests and forward them to django app.
Here is how django.wsgi look like:

import os, sys
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/..')
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
 
os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
os.environ['PYTHON_EGG_CACHE'] = '/tmp/python-eggs'
 
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

As you can see, django.wsgi handler will append path of project directory into PythonPath automatically.
Now we want to do something similar in settings.py for MEDIA_ROOT.
Relevant fragments of settings.py:

import os
BASE = os.path.dirname(__file__)
PROJECT_DIR = os.path.dirname(os.path.abspath(__file__))
 
MEDIA_ROOT = os.path.join(BASE, 'site-media')
MEDIA_URL = '/site-media/'
ADMIN_MEDIA_PREFIX = '/admin-media/'

That’s all folks. You can now reload apache with command ‘apache2ctl graceful’ run as root and your great app should be up&running. Oh yes, don’t forget to install mod_wsgi for Apache first ;)


COMMENTS / 4 COMMENTS

Your virtual servers will most likely be sharing /tmp, which would be a potential security issue if another process were able to corrupt the python egg cache.

cd34 added these pithy words on Sep 27 09 at 6:39 am

That is definitely good point, however I think can be easily fixed smart way. I’ll try it for my django apps sometime and update the article then.
Thanks

jsk added these pithy words on Sep 27 09 at 9:16 pm

Documentation doesn’t use __file__ relative path magic because it would confuse most people who wouldn’t know what that magic variable is for. Things would only get worse when they try and customise it for their own purposes because they ignore the documentation about where to place the WSGI script file, just as you ignored the documentation and didn’t put it in an ‘apache’ subdirectory of Django site. You should perhaps go reread the documentation for Django integration on the mod_wsgi site about why an ‘apache’ subdirectory is used.

Graham Dumpleton added these pithy words on Dec 24 09 at 2:01 am

Your virtual servers will most likely be sharing /tmp, which would be a potential security issue if another process were able to corrupt the python egg cache.

Bruce added these pithy words on May 19 10 at 6:20 pm

SPEAK / ADD YOUR COMMENT
Comments are moderated.

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Return to Top