...making Linux just a little more fun!

Installing/Configuring/Caching Django on your Linux server

By Anderson Silva and Steve 'Ashcrow' Milner

In today's world, web development is all about turnaround. Businesses want to maximize production outcome while minimizing development and production time. Small, lean development teams are increasingly becoming the norm in large development departments. Enter Django: a popular Python web framework that invokes the RWAD (rapid web application development) and DRY (don't repeat yourself) principles with clean, pragmatic design.

This article is not about teaching you how to program in Python, nor how to use the Django framework. It's about showing how to promote your Django applications onto an existing Apache or Lighttpd environment.

We will conclude with a simple way that you can improve the performance of your Django application by using caching to speed up access time. This article also assumes that you are running Fedora as your web application server, but all the packages mentioned in this article are also available in many OS's including under the Extra Packages for Enterprise Linux repository, which means these instructions should also be valid under Red Hat Enterprise Linux or CentOS servers.

What you need

You must have Django installed:

$ yum install Django

If you want to serve Django apps under Apache you will need mod_wsgi:

$ yum install httpd mod_wsgi

If you want to serve Django apps under Lighttpd:

$ yum install lighttpd lighttpd-fastcgi python-flup

Installing memcached to 'speed up' Django apps:

$ yum install memcached python-memcached

Starting a new Django project

1. Create a development workspace.

$ mkdir -p $LOCATION_TO_YOUR_DEV_AREA 
$ cd $LOCATION_TO_YOUR_DEV_AREA

2. Start a new base Django project. This creates the boiler plate project structure.

$ django-admin startproject my_app

3. Start the Django development web server on port 8080 (or whatever other port you'd like).

Note: The development web server is just for testing and verification. Do not use it as a production application server!

$ python manage.py runserver 8080

4. Run your Django project under Apache with mod_wsgi by enabling mod_wsgi. Note that to do this you will need to have your project in an SELinux friendly location (don't use home directories!) as well as readable by apache. On Fedora mod_wsgi is auto added upon install via /etc/httpd/conf.d/wsgi.conf. Upon restarting of apache, the module will be loaded.

5. Create virtual hosts by creating a new file at /etc/httpd/conf.d/myapp.conf.

WSGIScriptAlias / /path/to/myapp/apache/django.wsgi

DocumentRoot /var/www/html/
ServerName your_domain_name
ErrorLog logs/my_app-error.log
CustomLog logs/my_app-access_log common
6. In step 5 we defined a script alias and now we need to create the wsgi file it references.
import os
import sys

import django.core.handlers.wsgi

# Append our project path to the system library path
sys.path.append('/path/to/')

# Sets the settins module so Django will work properly
os.environ['DJANGO_SETTINGS_MODULE'] = 'myapp.settings'

# sets application (the default wsgi app) to the Django handler
application = django.core.handlers.wsgi.WSGIHandler()

Running your Django project under Lighthttpd with fastcgi

The first thing you must do is start up your FastCGI server.

./manage.py runfcgi method=prefork socket=/var/www/myapp.sock pidfile=django_myapp.pid

Then modify your lighttpd.conf file to use the FastCGI server.

server.document-root = "/var/www/django/"
fastcgi.server = (
    "/my_app.fcgi" => (
        "main" => (
            # Use host / port instead of socket for TCP fastcgi
            # "host" => "127.0.0.1",
            # "port" => 3033,
            "socket" => "/var/www/my_app.sock",
            "check-local" => "disable",
        )
    ),
)
alias.url = (
    "/media/" => "/var/www/django/media/",
)
url.rewrite-once = (
    "^(/media.*)$" => "$1",
    "^/favicon\.ico$" => "/media/favicon.ico",
    "^(/.*)$" => "/my_app.fcgi$1",
)

Setting up caching in Django

Django has many different caching backends, including database, memory, filesystem, and the ever popular memcached. According to http://www.danga.com/memcached/, memcached is "a high-performance, distributed memory object caching system, generic in nature, but intended for use in speeding up dynamic web applications by alleviating database load." It's used by high traffic sites such as Slashdot and Wikipedia. This makes it a prime candidate for caching in your cool new web app.

First, install memcached.

$ yum install memcached

Next, install the python bindings for memcached.

$ yum install python-memcached

Next, verify that memcached is running using the memcached's init script.

$ /etc/init.d/memcached status 
memcached (pid 6771) is running...

If it's not running, you can manually start it.

$ /sbin/service memcached start

If you want to make sure it will automatically start every time after a reboot:

$ /sbin/chkconfig --level 35 memcached on

Now that you have verified that memcached is running, you will want to tell your Django application to use memcached as it's caching backend. You can do this by adding a CACHE_BACKEND entry to your settings.py file.

CACHE_BACKEND = 'memcached://127.0.0.1:11211/'

The format is "backend://host:port/" or "backend:///path" depending on the backend chosen. Since we are using memcached, we have the option to run multiple daemons on different servers and share the cache across multiple machines. If you want to do this all you must do is add in the servers:port combinations in the CACHE_BACKEND and separate them by semicolons. In this example we share the cache across three different memcached servers:

CACHE_BACKEND = 'memcached://127.0.0.1:11211;192.168.0.10:11211;192.168.0.11/'

For more information on the different types of caching that can be performed in the Django framework, please refer to their official documentation.

Finally, whenever you are ready to get your applications into production, you can always write your own Django service script, so your application can start up at boot time.

The original article was published on June 5th, 2008 by Red Hat Magazine, and revised for the 2010 November Issue of Linux Gazette.


Share

Talkback: Discuss this article with The Answer Gang

Anderson Silva


[BIO]

Anderson Silva works as an IT Release Engineer at Red Hat, Inc. He holds a BS in Computer Science from Liberty University, a MS in Information Systems from the University of Maine. He is a Red Hat Certified Architect and has authored several Linux based articles for publications like: Linux Gazette, Revista do Linux, and Red Hat Magazine. Anderson has been married to his High School sweetheart, Joanna (who helps him edit his articles before submission), for 11 years, and has 3 kids. When he is not working or writing, he enjoys photography, spending time with his family, road cycling, watching Formula 1 and Indycar races, and taking his boys karting,


Steve 'Ashcrow' Milner


[BIO]

Steve 'Ashcrow' Milner works as a Security Analyst at Red Hat, Inc. He is a Red Hat Certified Engineer and is certified on ITIL Foundations. Steve has two dogs, Anubis and Emma-Lee who guard his house. In his spare time Steve enjoys robot watching, writing open code, caffeine, climbing downed trees and reading comic books.


Copyright © 2010, Anderson Silva and Steve 'Ashcrow' Milner. Released under the Open Publication License unless otherwise noted in the body of the article. Linux Gazette is not produced, sponsored, or endorsed by its prior host, SSC, Inc.

Published in Issue 180 of Linux Gazette, November 2010

Tux