Patter's Home

Django FastCGI & Lighttpd Setup

Multiple site (django project) setup using FastCGI & lighttpd on Debian.

/etc/init.d/django

FastCGI init.d script from Django Documentation modified to use named unix sockets for communication, so if 1 django site refuses to start, it won't affect the site mappings in lighttpd.
Initial setup:
#!/bin/bash
### BEGIN INIT INFO
# Provides:          FastCGI servers for Django
# Required-Start:    networking
# Required-Stop:     networking
# Default-Start:     2 3 4 5
# Default-Stop:      S 0 1 6
# Short-Description: Start FastCGI servers with Django.
# Description:       Django, in order to operate with FastCGI, must be started
#                    in a very specific way with manage.py. This must be done
#                    for each DJango web server that has to run.

#### SERVER SPECIFIC CONFIGURATION
DJANGO_SITES="patter secure" # space-separated list
SITES_PATH=/home/httpd/django
RUNFILES_PATH=$SITES_PATH/run
HOST=127.0.0.1
RUN_AS=www-data
FCGI_METHOD=threaded
#### DO NOT CHANGE ANYTHING AFTER THIS LINE!
set -e

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DESC="FastCGI servers"
NAME=$0
SCRIPTNAME=/etc/init.d/$NAME

#
#       Function that starts the daemon/service.
#
d_start()
{
    # Starting all Django FastCGI processes
    for SITE in $DJANGO_SITES
    do
        echo -n ", $SITE"
        if [ -f $RUNFILES_PATH/$SITE.pid ]; then
            echo -n " already running"
        else
            start-stop-daemon --start --quiet \
                       --pidfile $RUNFILES_PATH/$SITE.pid \
                       --chuid $RUN_AS --exec /usr/bin/env -- python \
                        $SITES_PATH/$SITE/manage.py runfcgi \
		       	socket=$RUNFILES_PATH/$SITE.sock \
			pidfile=$RUNFILES_PATH/$SITE.pid
            chmod 400 $RUNFILES_PATH/$SITE.pid
        fi
    done
}

#
#       Function that stops the daemon/service.
#
d_stop() {
    # Killing all Django FastCGI processes running
    for SITE in $DJANGO_SITES
    do
        echo -n ", $SITE"
        start-stop-daemon --stop --quiet --pidfile $RUNFILES_PATH/$SITE.pid \
                          || echo -n " not running"
        if [ -f $RUNFILES_PATH/$SITE.pid ]; then
           rm $RUNFILES_PATH/$SITE.pid
        fi
    done
}

ACTION="$1"
case "$ACTION" in
    start)
        echo -n "Starting $DESC: $NAME"
        d_start
        echo "."
        ;;

    stop)
       echo -n "Stopping $DESC: $NAME"
        d_stop
        echo "."
        ;;

    restart|force-reload)
        echo -n "Restarting $DESC: $NAME"
        d_stop
        sleep 1
        d_start
        echo "."
        ;;

    *)
        echo "Usage: $NAME {start|stop|restart|force-reload}" >&2
        exit 3
        ;;
esac

exit 0

lighttpd.conf

This should be added to your default lighttpd configuration. This first section applies to all sites, then each django site requires its own configuration section.
server.modules += (
    "mod_alias",
    "mod_rewrite",
)

alias.url += (
    "/static/admin" => "/usr/share/pyshared/django/contrib/admin/media/"
)

url.rewrite-once += (
    "^(/static.*)$" => "$1",
    "^(/.*)$" => "/mysite.fcgi$1",
)

Per-site configuration

$HTTP["host"] =~ "^patter.local" {
    fastcgi.server = (
        "/mysite.fcgi" => (
            "main" => (
                "socket" => "/home/httpd/django/run/patter.sock",
                "check-local" => "disable",
            )
        ),
    )
}