Roshan Book

My Tech Notebook

Tag Archives: Django

Django Deployment Guide For Ubuntu


Ignite your Django projects with nginx, Apache and mod_wsgi

There’s a time when every Django developer has to think about deployment scenarios, when I first did it last year I thought that a setup involving Lighty, Apache, mod_proxy and mod_python was a good choice but my first approach was not the best. I put Apache as the front server, handling requests for Django generated pages and passing, via mod_proxy, requests for static content to Lighty on the back. A setup where Apache had to work even for files that wasn’t supposed to serve was a very bad idea.

After many helpful comments and some more reading I realized that it was better having the server for static content on the front and Apache, which still talks to Django, on the back.

I replaced Lighty with nginx, which according to many seems to be more stable, and opted for mod_wsgi instead of mod_python to make Apache talk to Django. mod_wsgi has a lower memory overhead and it’s suitable for high performance sites. There’s no need for mod_proxy on Apache anymore as nginx is the one in charge of the proxy work now.

This is an easy to follow and very focused guide for developers who know how to handle their servers so I won’t consider security issues, memcached, Django installation, databases or basic GNU/Linux, Apache and DNS settings. Of course all of those subjects are important and you should take care of them.

The plan

This guide includes all the steps needed to:

  • Setup a domain for your Django project.
  • Create a simple directory layout for Django sites.
  • Configure Apache with mod_wsgi for Django.
  • Configure nginx.
  • Serve Django admin media files.
  • Turn on the heat and show your greatest and latest Django stuff to the world.

After following all the steps you will have a Django site running with nginx on the front and Apache on the back. nginx will manage all static content and will pass Django requests to Apache and mod_wsgi.

I have tested on three Ubuntu servers (two running 8.10, Intrepid Ibex, and one 7.10, Gutsy Gibbon) but everything should be pretty similar in other GNU/Linux distributions.

Shall we start?

Setup a domain for your Django project

Many of us run more than one website in one server, I have several with Drupal and a few with Django living in one box, so let’s consider a two domains scenario: will host the Django project anything else. Most of the work will focus in, I just mention to give you some context. Obviously you should replace all the domain names in this guide with yours.

We’ll use a couple of private IP addresses for now and will replace them with public ones and setup in a DNS server when going live. For this guide I’ll just add to /etc/hosts, which is what I usually do in my development environment:

I’m using and two ports, 80 and 8080, for serving the Django site at The default port 80 will be used by nginx to serve static content and Django will look for files under the /media directory. Port 8080 will be used by Apache to handle Django requests.

Create a simple directory layout for Django sites

Directory layouts depend on personal preferences, I currently use a /home/alexis/djcode directory for all my Django coding and the new project will be called cataybea; hence, we have to run:

mkdir /home/alexis/djcode cd /home/alexis/djcode/ startproject cataybea

Now let’s create some additional directories:

mkdir /home/alexis/djcode/cataybea/apache mkdir /home/alexis/djcode/cataybea/logs mkdir /home/alexis/djcode/cataybea/media

What are they for? apache will contain a Python script to setup mod_wsgi, logs will store Apache and nginx logs and media is the directory nginx will use to serve static files for our Django project.

You can later manage the whole /home/alexis/djcode/cataybea directory with your favorite version control tool.

Take note of the correct paths for using later in the configuration files.

Configure Apache with mod_wsgi for Django

I assume you already have Apache working correctly and just need to tweak a little for our Django setup. As we’ll be running two web servers at once we must make sure that IP addresses and ports won’t conflict. Let’s edit /etc/apache2/ports.conf:

Listen Listen #Listen 80

I have specified IP addresses and ports to listen. Notice I commented the default Listen 80 as it means Apache would listen to that port in all IP addresses. If you want to use SSL take care of the 443 port in the same way.

If you are using virtual hosts in Apache confirm it’s listening to the correct IP addresses and ports, I have this in/etc/apache2/sites-enabled/


Restart Apache and make sure your Apache sites work normally. I’m obsessed with testing at every step in the way and I suggest you are too.

sudo /etc/init.d/apache2 restart

Now it’s time to add mod_wsgi to Apache. The latest versions of Ubuntu have it in the repository:

sudo apt-get install libapache2-mod-wsgi

For older versions of Ubuntu, such as Gutsy, you need to find the .deb file and use something like dpkg -i to install.

Now it’s time to create the Apache configuration file for in /etc/apache2/sites-available/

<VirtualHost> ServerAdmin ServerName ServerAlias <Directory /home/alexis/djcode/cataybea/apache/> Order deny,allow Allow from all </Directory> LogLevel warn ErrorLog /home/alexis/djcode/cataybea/logs/apache_error.log CustomLog /home/alexis/djcode/cataybea/logs/apache_access.log combined WSGIDaemonProcess user=www-data group=www-data threads=25 WSGIProcessGroup WSGIScriptAlias / /home/alexis/djcode/cataybea/apache/cataybea.wsgi </VirtualHost>

Notice the IP address and port: This site won’t be accessed directly but via proxy from nginx. We’ll set that up in the next section.

Now we need a Python script to configure our Django project to use mod_wsgi, create/home/alexis/djcode/cataybea/apache/cataybea.wsgi and put the following code inside:

import os, sys apache_configuration= os.path.dirname(__file__) project = os.path.dirname(apache_configuration) workspace = os.path.dirname(project) sys.path.append(workspace) sys.path.append(‘/usr/lib/python2.5/site-packages/django/’) sys.path.append(‘/home/alexis/djcode/cataybea’) os.environ[‘DJANGO_SETTINGS_MODULE’] = ‘cataybea.settings’ import django.core.handlers.wsgi application = django.core.handlers.wsgi.WSGIHandler()

Don’t restart Apache yet as we need to complete a few more steps.

Configure nginx

nginx will do two things: serve static content from and pass all other requests to Apache. Let’s install it first:

sudo apt-get install nginx

Now remove the nginx default site:

sudo rm /etc/nginx/sites-enabled/default

Apache and nginx should be using the same user, for Ubuntu this is www-data, and your /etc/nginx/nginx.confshould look like this:

user www-data; worker_processes 2; error_log /var/log/nginx/error.log; pid /var/run/; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; access_log /var/log/nginx/access.log; sendfile on; tcp_nopush on; keepalive_timeout 65; tcp_nodelay on; gzip on; include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; }

worker_processes can be set to the number of cores in your server, in my case that’s just 2.

Configure a the site on nginx by creating /etc/nginx/sites-available/

server { listen; server_name; access_log /home/alexis/djcode/cataybea/logs/nginx_access.log; error_log /home/alexis/djcode/cataybea/logs/nginx_error.log; location / { proxy_pass; include /etc/nginx/proxy.conf; } location /media/ { root /home/alexis/djcode/cataybea/; } }

then running:

sudo ln -s /etc/nginx/sites-available/ /etc/nginx/sites-enabled/

and finally creating the file that will take care of proxying Django requests to Apache, we’ll call it/etc/nginx/proxy.conf and put this inside:

proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; client_max_body_size 10m; client_body_buffer_size 128k; proxy_connect_timeout 90; proxy_send_timeout 90; proxy_read_timeout 90; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k;

Notice $host, $remote_addr and $proxy_add_x_forwarded_for are variables that will be handled by nginx, you don’t need to change anything else in proxy.conf for a basic setup. When I started playing with nginx I thought these had to be replaced by me, I was wrong.

Finally restart nginx:

sudo /etc/init.d/nginx restart

and Apache:

sudo /etc/init.d/apache2 restart

That should be it! If you visit you should see some Django content (could be the welcome page, some of your views or a 404 page depending on your project status). To try the nginx media server create a test.htm file with some dummy content in /home/alexis/djcode/cataybea/media and visit

Serve Django admin media files (optional)

If you will use the Django admin application edit /home/alexis/djcode/cataybea/, make sure your database settings are correct, add ‘django.contrib.admin’ to the INSTALLED_APPS tuple and change theADMIN_MEDIA_PREFIX like this:

ADMIN_MEDIA_PREFIX = ‘/media/admin/’

Let’s enable the admin url by editing /home/alexis/djcode/cataybea/, uncommenting these two lines:

from django.contrib import admin admin.autodiscover()

and adding this to urlpatterns:

(r’^admin/’, include(,

Now let’s create a symbolic link to the media files for the Django’s administration section:

cd /home/alexis/djcode/cataybea/media ln -s /usr/lib/python2.5/site-packages/django/contrib/admin/media/ admin

And finally let’s create the administration user and the required tables in the database:

cd /home/alexis/djcode/cataybea/media python syncdb

As with every other modifications in your Django code you will have to reload Apache for changes to take effect:

sudo /etc/init.d/apache2 reload

Visit,including the trailing slash, and you should be in business.


Django email setup on Hostgator

Originally published at
On Hostgator it is possible to run Django applications with FastCgi, but it has only sendmail as email back-end which is not included in Django.

Hopefully there is a snipets to resolve this limitation. You just needed to change the path of the sendmail file and it was ready to run. The location of sendmail is “/usr/sbin/sendmail” on our Hostgator server.

And the email backend should be configured in your by adding the following line:

EMAIL_BACKEND = ‘sendmail.EmailBackend’

Setting up rancho in django

Follow instructions listed in here

Installing psycopg2 :

Installing mysqldb –

to install dependencies inside virtual env:

install virtuaev -pip install virtualenv
install python image library-
pip install --no-index -f -U PIL
install mysqldb- pip install MySQL-python
install pytz - pip install pytz
install pisa - pip install pisa

Go to wikiboard view change ho.pisa module to xhtml2pdf.pisa

add ’django.middleware.csrf.CsrfResponseMiddleware’, to settings

add mysql only as database setting

install all rancho needed module via sudo easy_install modulename

When you implement the project you get an error where you are unable to upload and message under any project. To solve this refer

Patch is at


To resolve tinymce>> error – cannot import smart_unicode

see patch

Setting up heroku with django and python

Getting django up and running on hostgator

This post was originally published at

I thought it would be fun this year to start learning Django, so here’s a bit about how to get it set up using Hostgator (I have a shared hosting account).

I am using Terminal on the MAC and the File Manager on the cPanel.

The first thing you have to do is enable SSH (shell access). To do this, log into your cPanel and go to “Billing”:

Then choose, “View Hosting Packages”:

Then, click the link that says, “Enable Shell Access“.

Next, write down your IP as shown in the cPanel (I blurred mine out for security purposes, but you can see what the section looks like here):

Also, write down your cPanel username and password, you will need this.

Open Terminal and the File Manager in cPanel. I keep both open at the same time to see what I am doing.

In your File Manager, you should see /home/your-username/. Then look for a folder called django. You should have this. If not, in Terminal, type the following to SSH to your account:

ssh -p 2222 your-username-goes-here@your-ip-goes-here

If this works (you might have to wait a moment while it connects to your site), you will be prompted for your password.

Type in your password (you won’t see it at all) then hit enter and wait.

If this is your first time, you will be asked about a key. Just say “yes”.

You might then get some message like, “The authenticity of this host can’t be established” and “RSA key fingerprint is blah blah blah”.

Don’t worry about this, if you like, write down the key in case you need it later. That’s it. You are now connected to your logged in to your account via SSH. Now type the following.

mkdir ~/django
cd ~/django
svn co

mkdir creates a folder called “django”.

cd changes where you are to inside of the “django” folder.

The last line gets the latest stable version of django and installs it into the “django” folder. You need to have subversion installed for this to work.

I can’t really remember if I had to install subversion on my version of OS X, I think it was already installed, but if not, you’ll have to install it. It’s free.

Then, create a directory for your projects inside of the django folder by typing:

mkdir ~/django/projects

You should now have a folder called “django” with two folders inside:

Now, to test if django is running, you make a test project.

In Terminal, type:

cd projects

This will switch you into the projects folder.

Then type: startproject newproject

This tells django to create a new project called, “newproject”.

Then type:

cd newproject
chmod +x
./ startapp newapp

If you go inside of your “newproject” folder you should now see the following:

This is your “newapp”. Yay, django is working…sort of

Next, you have to enable fastcgi (or, I suppose, django will run really slowly).

Create a new file called index.fcgi in your public folder:

Then change the permissions of the file to 755:

Next, edit the file and add the following (be sure to change “username” with your username for your account):

import sys, os, user

# sys.path.insert(0, "/usr/lib/python2.4")
sys.path.insert(0, "/home/your-username-goes-here/django")
sys.path.insert(0, "/home/your-username-goes-here/django/projects")
sys.path.insert(0, "/home/your-username-goes-here/django/projects/newproject")

# Switch to the directory of your project.

# Set the DJANGO_SETTINGS_MODULE environment variable.
os.environ['DJANGO_SETTINGS_MODULE'] = "newproject.settings"

from django.core.servers.fastcgi import runfastcgi
runfastcgi(method="threaded", daemonize="false")

Next, open the .htaccess that is in the same folder as index.fcgi.

AddHandler fcgid-script .fcgi
Options +FollowSymLinks
RewriteEngine On

RewriteRule (media/.*)$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(admin/.*)$ index.fcgi/$1 [L]

Next (and this is important) check your website. If you are getting a 500 error, open Terminal and log in to your account:

ssh -p 2222 your-username-goes-here@your-ip-goes-here

Then type:

which python

This should give you a message like:


If you are getting something different (for example, user/local/bin/python/), update your script to reflect this:


If all goes well, you should see this:

Below is my working code for hostgator

Below are my working code based on Robert code.

1. For curlgen.fcgi – change permission to 755

code is :
import sys, os, user

# sys.path.insert(0, “/usr/lib/python2.7”)
sys.path.insert(0, “/home/r5tpl/django/projects”)

# Switch to the directory of your project.

# Set the DJANGO_SETTINGS_MODULE environment variable.
os.environ[‘DJANGO_SETTINGS_MODULE’] = “newproject.settings”

from django.core.servers.fastcgi import runfastcgi
runfastcgi(method=”threaded”, daemonize=”false”)

For .htaccess code is
AddHandler fcgid-script .fcgi
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ curlgen.fcgi/$1 [QSA,L]

Django deployment on linux machine

Using Django with Apache and mod_python

Apache with mod_python currently is the most robust setup for using Django on a production server.

mod_python ( is an Apache plug-in that embeds Python within Apache and loads Python code into memory when the server starts. Code stays in memory throughout the life of an Apache process, which leads to significant performance gains over other server arrangements.

Django requires Apache 2.x and mod_python 3.x, and we prefer Apache’s prefork MPM, as opposed to the worker MPM.4


Configuring Apache is well beyond the scope of this book, so we’ll simply mention details as needed. Luckily, a number of great resources are available if you need to learn more about Apache. A few of them we like are as follows:
The free online Apache documentation, available via
Pro Apache, Third Edition (Apress, 2004) by Peter Wainwright, available via
Apache: The Definitive Guide, Third Edition (O’Reilly, 2002) by Ben Laurie and Peter Laurie, available via
Basic Configuration

To configure Django with mod_python, first make sure you have Apache installed with the mod_python module activated. This usually means having a LoadModule directive in your Apache configuration file. It will look something like this:3
LoadModule python_module /usr/lib/apache2/modules/

Then, edit your Apache configuration file and add the following:

SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
PythonDebug On

Make sure to replace mysite.settings with the appropriate DJANGO_SETTINGS_MODULE for your site.2

This tells Apache, “Use mod_python for any URL at or under ‘/’, using the Django mod_python handler.” It passes the value of DJANGO_SETTINGS_MODULE so mod_python knows which settings to use.

Note that we’re using thedirective, not thedirective. The latter is used for pointing at places on your filesystem, whereaspoints at places in the URL structure of a Web site.would be meaningless here.2

Apache likely runs as a different user than your normal login and may have a different path and sys.path. You may need to tell mod_python how to find your project and Django itself.4
PythonPath “[‘/path/to/project’, ‘/path/to/django’] + sys.path”

You can also add directives such as PythonAutoReload Off for performance. See the mod_python documentation for a full list of options.

Note that you should set PythonDebug Off on a production server. If you leave PythonDebug On, your users will see ugly (and revealing) Python tracebacks if something goes wrong within mod_python.

Restart Apache, and any request to your site (or virtual host if you’ve put this directive inside ablock) will be served by Django.


If you deploy Django at a subdirectory — that is, somewhere deeper than “/” — Django won’t trim the URL prefix off of your URLpatterns. So if your Apache config looks like this:

SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
PythonDebug On

then all your URL patterns will need to start with “/mysite/”. For this reason we usually recommend deploying Django at the root of your domain or virtual host. Alternatively, you can simply shift your URL configuration down one level by using a shim URLconf:
urlpatterns = patterns(”,
(r’^mysite/’, include(‘normal.root.urls’)),
Running Multiple Django Installations on the Same Apache Instance

It’s entirely possible to run multiple Django installations on the same Apache instance. You might want to do this if you’re an independent Web developer with multiple clients but only a single server.

To accomplish this, just use VirtualHost like so:1
NameVirtualHost *
# …
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
# …
SetEnv DJANGO_SETTINGS_MODULE mysite.other_settings

If you need to put two Django installations within the same VirtualHost, you’ll need to take a special precaution to ensure mod_python’s code cache doesn’t mess things up. Use the PythonInterpreter directive to give different directives separate interpreters:

# …

SetEnv DJANGO_SETTINGS_MODULE mysite.settings
PythonInterpreter mysite
SetEnv DJANGO_SETTINGS_MODULE mysite.other_settings
PythonInterpreter mysite_other
The values of PythonInterpreter don’t really matter, as long as they’re different between the two Location blocks.
Running a Development Server with mod_python

Because mod_python caches loaded Python code, when deploying Django sites on mod_python you’ll need to restart Apache each time you make changes to your code. This can be a hassle, so here’s a quick trick to avoid it: just add MaxRequestsPerChild 1 to your config file to force Apache to reload everything for each request. But don’t do that on a production server, or we’ll revoke your Django privileges.1

If you’re the type of programmer who debugs using scattered print statements (we are), note that print statements have no effect in mod_python; they don’t appear in the Apache log, as you might expect. If you have the need to print debugging information in a mod_python setup, you’ll probably want to use Python’s standard logging package. More information is available at Alternatively, you can or add the debugging information to the template of your page.2
Serving Django and Media Files from the Same Apache Instance

Django should not be used to serve media files itself; leave that job to whichever Web server you choose. We recommend using a separate Web server (i.e., one that’s not also running Django) for serving media. For more information, see the “Scaling” section.1

If, however, you have no option but to serve media files on the same Apache VirtualHost as Django, here’s how you can turn off mod_python for a particular part of the site:

SetHandler None

Change Location to the root URL of your media files.

You can also use to match a regular expression. For example, this sets up Django at the site root but explicitly disables Django for the media subdirectory and any URL that ends with .jpg, .gif, or .png:

SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
SetHandler None
SetHandler None

In all of these cases, you’ll need to set the DocumentRoot directive so Apache knows where to find your static files.

Python web development–1


Requirements :

Web Server : CherryPy

Server side scripting language : Python

Editor : titanium studio

Database engine : SQL Lite

Object relational mapper : SQL Alchemy

Javascirpt Library  :Jquery and jqueryUI

Testing  – Unit Test

Version amangement – Git and SVN



%d bloggers like this: