Django Deployment: Upstart statt Supervisor

Geschrieben am 28. November 2014

Heute habe ich meine erste Django-Applikation, die ich auf der Basis von Python 3 geschrieben habe, in Produktivbetrieb genommen; bisher liefen alle Django-Installationen noch auf Python 2.

An meinem bisherigen Production Tech Stack musste ich eine Kleinigkeit ändern. Bisher habe ich Supervisor verwendet, um die Applikation zu starten und zu überwachen. Doch leider ist Supervisor nicht kompatibel zu Python 3. Da es sich bei der Produktivmaschine um eine Ubuntu VM handelt, habe ich mich dafür entschieden, schlicht Upstart zu verwenden. In einiger Zeit wird dann wohl der Wechsel zu systemd kommen. Aber heute tut es Upstart.

Dazu lege ich eine Datei /etc/init/my-app.conf mit folgendem Inhalt an:

description "my-app"
start on runlevel [2345]
stop on runlevel [06]
respawn
respawn limit 10 5
exec /home/user/webapps/my-app/my-app/gunicorn_start

Anschließend kann ich den neuen Dienst registrieren:

$ sudo ln -fs /lib/init/upstart-job /etc/init.d/my-app

Damit der Dienst beim Hochfahren des System gestartet wird, sage ich:

$ sudo update-rc.d my-app defaults

Und nun per Hand starten:

$ sudo service my-app start

Das war schon alles. Das Skript gunicorn_start sieht übrigens wie folgt aus:

#!/bin/bash

NAME="my-app"                                        # Name of the application
DJANGODIR=/home/user/webapps/my-app/my-app           # Django project directory
SOCKFILE=/home/user/webapps/my-app/run/gunicorn.sock # we will communicte using this unix socket
USER=user                                            # the user to run as
GROUP=user                                           # the group to run as
NUM_WORKERS=3                                        # how many worker processes should Gunicorn spawn
DJANGO_SETTINGS_MODULE=my-app.settings               # which settings file should Django use
DJANGO_WSGI_MODULE=my-app.wsgi                       # WSGI module name

echo "Starting $NAME"

# Activate the virtual environment
PATH=/usr/local/bin:/usr/bin:/bin
source /etc/bash_completion.d/virtualenvwrapper
cd $DJANGODIR
export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
export PYTHONPATH=$DJANGODIR:$PYTHONPATH
workon my-app

# Create the run directory if it doesn't exist
RUNDIR=$(dirname $SOCKFILE)
test -d $RUNDIR || mkdir -p $RUNDIR

# Start your Django Unicorn
# Programs meant to be run under supervisor should not daemonize themselves (do not use --daemon)
exec /home/user/.virtualenvs/my-app/bin/gunicorn ${DJANGO_WSGI_MODULE}:application \
  --name $NAME \
  --workers $NUM_WORKERS \
  --user=$USER --group=$GROUP \
  --log-level=debug \
  --bind=unix:$SOCKFILE