django-hosting.de

Django mit Lighttpd und mod_fastcgi betreiben

Lighttpd ist ein Webserver, welcher Resourcen schont und für hohe Lasten optimiert ist. Mittels mod_fastcgi kann man Django Applikationen betreiben. In Version 1.5 wird eventuell bald WSGI als mögliches Protokoll implementiert.

Django läuft in diesem Fall als eigener Prozess, wobei es zwei grundsätzliche Methoden gibt diese(n) Prozess(e) zu starten:

  • Lighttpd startet den Django Daemon.
  • Ein (Init-)Script startet den Django Daemon.

Ersteres ist auf jeden Fall die unkompliziertere Methode, da man sich um weniger kümmern muss. Allerdings ist man dafür auch etwas in der Flexibilität eingeschränkt.

Es gibt zwei unterschiedliche Methoden wie Lighttpd mit Django kommuniziert:

  • Per TCP/IP Socket. Vorteil: Django kann sogar auf einem anderem Server laufen als Lighttpd. Lighttpd kann sogar ein Loadbalancing über mehrere Django Backend-Server machen, so dass hier kein Flaschenhald entsteht.
  • Per Unix-Socket. Dieses Verfahren wird man wohl wählen, wenn Django auf dem selben Server Lighttpd läuft und zudem Lighttpd das starten des Django Daemons übernimmt.

[...]

Hier ein paar Listings meiner Konfiguration mit Django und Lighttpd, zuerst der entscheidende Teil aus der lighttpd.conf:

fastcgi.server = (
        "/app.fcgi" => (
                "main" => (
                        "socket" => "/tmp/app.sock",
                        "check-local" => "disable",
                )
        ),
)

alias.url = (
        "/media/" => "/usr/lib/python2.4/site-packages/django/contrib/admin/media/",
        "/static/" => "/srv/http/",
        "/favicon.ico" => "/srv/http/www.example.com/favicon.ico",
)

url.rewrite-once = (
        "^(/media.*)$" => "$1",
        "^(/static.*)$" => "$1",
        "^(/favicon.ico)$" => "$1",
        "^(/.*)$" => "/app.fcgi$1",
)

app.fcgi ist hier, ander als beim ApacheModWsgi Setup, keine Datei, sondern nur wird nur als Name intern im Lighttpd benutzt um den Request zu routen. Eigentlich muss man diese Konfiguration von unten nach oben lesen. Mit url.rewrite-once wird zunächst festgelegt, welche URLs wie bearbeitet werden sollen. Alle URLs, die weder mit /media oder /static beginnen und nicht /favicon.ico lauten werden an app.fcgi weitergeleitet. Im Block alias.url wird festgelegt, dass /media/ auf auf die Admin Media Daten zeigt, diese URL enspricht also settings.ADMIN_MEDIA_PREFIX. URLs die mit /static beginnen zeigen auf das MEDIA_ROOT der Applikation und entsprechen somit settings.MEDIA_URL.

Zu guter Letzt sei bemerkt, dass in diesem Beispiel Lighttpd über einen Unix-Socket (/tmp/app.sock) mit Django kommuniziert. Der Django Prozess wird außerdem nicht vom Lighttpd verwaltet (gestartet/gestoppt) sondern von einem externen Script, welches bei mir so aussieht:

#! /bin/bash

WD=/home/users/www.example.com/myproject
PIDFILE=${WD}/app.pid
PYTHON=/usr/bin/python2.4
SOCKET=/tmp/app.sock

case "$1" in
        start)
                $PYTHON $WD/manage.py runfcgi socket=$SOCKET daemonize=true method=prefork pidfile=$PIDFILE
                sleep 3
                chmod a+rwx $SOCKET
                ;;

        stop)
                kill `cat $PIDFILE`
                ;;

        restart)
                $0 stop && $0 start
                ;;

        *)
                echo "Usage: $0 {start|stop|restart}"
                ;;
esac
exit 0

Sollen Lighttpd und Django statt über einen Unix-Socket lieber per TCP/IP kommunizieren, damit Django z.B. auf einem extra Server laufen kann, ändert sich eigentlich nicht viel. In der Lighttpd Konfiguration sieht der fastcgi.server Block dann so aus:

fastcgi.server = (
        "/app.fcgi" => (
                "main" => (
                       "host" => "192.168.100.5",
                        "port" => 9111,
                        "check-local" => "disable",
                )
        ),
)

Und das Script welches den Django Daemon startet dann z.B. so:

#! /bin/bash

WD=/home/users/www.example.com/myproject
PIDFILE=${WD}/django.pid
PYTHON=/usr/bin/python2.4
HOST=192.168.100.5
PORT=9111

case "$1" in
        start)
                $PYTHON $WD/manage.py runfcgi host=$HOST port=$PORT daemonize=true method=prefork pidfile=$PIDFILE
                ;;

        stop)
                kill `cat $PIDFILE`
                ;;

        restart)
                $0 stop && $0 start
                ;;

        *)
                echo "Usage: $0 {start|stop|restart}"
                ;;
esac
exit 0

Die oben angegebene Konfiguration unterscheidet sich eigentlich nicht von der aus der offiziellen Django Lighttpd Konfiguration.

To be continued ...

View Plain  |  Index  |  Home

Showing: head, History: head [6]