
I believe that every good developer should be able to deploy a backend and work with it. A smart developer will also use an application framework to make his life easier and be more productive. Django is the application framework I love. It is tested, complete and sexy, written in beautiful Python.
The official documentation is also awesome, but it is not enough if you want help with deployment. We will be deploying Django using Apache 2.x and mod_wsgi running in daemon mode (recommended). The daemon mode will create a separate dedicated process for running your Django application that is independent from the Apache child processes.
I am assuming that you have Django already installed, if not it is never late to install the latest version.
wget http://www.djangoproject.com/download/1.3.1/tarball/
tar -xzvf Django-1.3.1.tar.gz
sudo python setup.py install
Make some love
Let’s also assume that the folder where we keep our Django projects is
/var/django and we will be working on a project named love
django-admin.py startproject love
Create the application wsgi entry point
Now we need to create a wsgi entry point for our project, the best place to put it is under /var/django/love/apache. You want to have it on its own folder, isolated for security reasons, since our web server will be accessing it. The recommended filename is django.wsgi which is just a convention.
import sys,os
sys.path.append("/var/django")
sys.path.append("/var/django/love")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "love.settings")
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
Configure Apache
Time to configure our Apache server and let it know about our project and the wsgi entry point. Edit your vhost configuration and add:
WSGIScriptAlias / /var/django/love/apache/django.wsgi
<Directory /var/django/love/apache>
Order deny,allow
Allow from all
</Directory>
Now the root url is aliased with our wsgi entry point which runs the application.
Enable wsgi daemon mode
We do not want to run wgsi in embedded mode and adding the following lines will enable daemon mode.
WSGIDaemonProcess love.me user=love group=love threads=25
WSGIProcessGroup love.me
It is recommended to create a non privileged user to run the daemon process. I created the user/group love to match our project name. We are also setting the name of the process and the process group to love.me, matching our domain name (you can pick any name you want though).
The socket permission issue
The wsgi configuration looks complete but there is still a problem. Apache might be unable to communicate with the wsgi daemon process.
That happens because the socket that is used for the communication is placed into the Apache runtime environment which is readable only by Apache and not the wsgi daemon process. To solve this edit your conf.d/wsgi.conf and add:
WSGISocketPrefix /var/run/wsgi
Let’s view it
We are done, lets create a view to see it working. Create a views.py file in your project folder and add:
from django.http import HttpResponse
def index(request):
return HttpResponse("Django love!")
Then set the url configuration to point to the new view, edit url.conf and set your urls patterns to:
urlpatterns = patterns('',
url(r'^$', 'love.views.index'),
)
^$ matches empty strings, it means match what starts and ends with nothing in between, so that will match our root url.
Visit your root URL and check, I hope it works!
If you have some kind of configuration issue check http://code.google.com/p/modwsgi/wiki/ConfigurationIssues or contact me, I might be able to help.
There are two more things that I want to include in this tutorial, serving static files and source code reloading.
Serving static files
The Apache configuration will be entirely complete and ready to go by adding some more directives for serving the static files of your project, edit your vhost configuration and add:
Alias /robots.txt /var/django/love/static/robots.txt
Alias /favicon.ico /var/django/love/static/favicon.ico
Alias /static/ /var/django/love/static/
<Directory /var/django/love/static>
Order deny,allow
Allow from all
</Directory>
Alias /media/ /var/django/love/media/
<Directory /var/django/love/media>
Order deny,allow
Allow from all
</Directory>
AliasMatch ^/([^/]*\.css) /var/django/love/static/styles/$1
Remember to create the static, media and styles folders in your Django project and then edit settings.py and change the following parameters:
MEDIA_ROOT = '/var/django/love/media/'
MEDIA_URL = '/media/
STATIC_ROOT = '/var/django/love/static/'
STATIC_URL = '/static/'
Source code reloading
Every time a file is changed Apache has to be restarted to load the changes when running in the default embedded mode.
When running in daemon mode, which is our case, the daemon process and therefore the code will be reloaded everytime the django.wsgi file is changed. So a quick way to force a code reload would be to touch the file. But that is not convenient enough and you should not poke that file all the time.
To enable proper source code reloading do the following:
1. Create a monitor.py file and add the code from the section Monitoring For Code Changes as shown in http://code.google.com/p/modwsgi/wiki/ReloadingSourceCode
2. Edit the django.wsgi file and add:
import monitor
monitor.start(interval=1.0)
monitor.track(os.path.join(os.path.dirname(__file__), 'site.cf'))
Happy development! Remember to remove the source code monitoring in a production environment to avoid the extra overhead.
Special thanks to the great Django official documentation
https://docs.djangoproject.com/en/1.3/
and the amazing modwsgi documentation from Graham Dumpleton
http://code.google.com/p/modwsgi/