Home Blog CV Projects Patterns Notes Book Colophon Search

Treating a Python Application as a Daemon on Debian

28 Feb, 2010

Contents

There are two approaches to writing daemon applications like servers in Python. The first is to handle all the tasks of sarting and stopping daemons in Python code itself. The easiest way to do this is with the python-daemon package which might eventually make its way into the Python distribution. The other approach is to use the tools supplied by the operating system. In the case of Debain, this means writing an init script which makes use of the start-stop-daemon program.

A Python Server Daemon

Let's consider the case where we have a server written in Python. The command to start it looks like this (using absolute paths):

/home/james/env/bin/python /home/james/Desktop/Cur/Carbage/code/carbage/run /home/james/Desktop/Cur/Carbage/instance/dirac.3aims.com/test.conf serve

We'd like to be able to have the server run in the background, for it to be started when Debian boots and to have a process ID file so that we can stop the server, or check that it is running.

The bash script below achieves this:

#!/bin/bash

DAEMON=/root/Carbage/instance/bifferboard/env/bin/python
ARGS="/root/Carbage/code/carbage/run.py /root/Carbage/instance/bifferboard/app.conf serve"
PIDFILE=/root/Carbage/instance/bifferboard/serve.pid

case "$1" in
  start)
    echo "Starting server"
    /sbin/start-stop-daemon --start --pidfile $PIDFILE \
        --user www-data --group www-data \
        -b --make-pidfile \
        --chuid www-data \
        --exec $DAEMON -- $ARGS
    ;;
  stop)
    echo "Stopping server"
    /sbin/start-stop-daemon --stop --pidfile $PIDFILE --verbose
    ;;
  *)
    echo "Usage: /etc/init.d/carbage-serve {start|stop}"
    exit 1
    ;;
esac

exit 0

Save this in the /etc/init.d directory. In this example we'll call it carbage. You'll need to make the file executable:

chmod +x /etc/init.d/carbage

You can now start the server like this:

/etc/init.d/carbage start

and stop it like this:

/etc/init.d/carbage stop

Adding to Cron

If you run the command to start the server when it is already running, the command gets ignored. This means it is safe to have the start command run every minute by a cron job so that if it stops for any reason, the downtime should be at most 60 seconds.

You should run this:

sudo crontab -e

and add the following line to the root crontab:

* * * * * /etc/init.d/carbage start

Cron jobs run commands in a very minimal environment without /sbin on the path so it is important that any commands in your init scripts use full paths. In this case we specified /sbin/start-stop-daemon so the cron jobs work.

Starting Automatically

Debian services get started as the operating system enters various runlevels. To have a service started and stopped at a particular runlevel you need to add symbolic links to the script from the various directories /etc/rc0.d, /etc/rc1.d ... /etc/rc6.d. The easiest way to do this is with the update-rc.d command.

To add the carbage command so it gets started automatically you would type this:

sudo update-rc.d -f carbage defaults

If you ever want to remove the symbolic links you can do so like this:

sudo update-rc.d -f carbage remove

You now have a daemon which can be started and stopped at will, gets checked every minute and restarted if it stops and which is automatically started and stopped as the system boots and shutsdown.

Further Reading

Man Pages:

Articles:

Copyright James Gardner 1996-2020 All Rights Reserved. Admin.