Ein bestimmtes Programm ablaufen zu lassen ist häufig ein Grund um einen virtuellen oder dedizierten Server zu betreiben. Wenn das Programm als Teil der verwendeten Linux-Distribution verfügbar ist, reicht das Installieren des Paketes und das Bearbeiten der Konfigurationsdateien üblicherweise aus. Falls das Programm aber aus einer externen Quelle kommt oder eine Eigenentwicklung ist, steht man selbst vor der Aufgabe dafür zu sorgen, dass es beim Systemstart automatisch gestartet wird. Außerdem ist es in der Entwicklungsphase oft sinnvoll, das Programm automatisch neu starten zu lassen, falls es durch einen Fehler abbricht. Vor einigen Jahren war es relativ einfach, ein Programm bei Systemstart starten zu lassen. Es musste nur ein passendes init-Script erstellt werden. Seit einiger Zeit setzen einige Linux-Distribution für den Systemstart auf upstart
oder systemd
anstelle von init
. Passende Konfiguration für alle Systeme bereitzustellen kann recht aufwendig werden. Zudem besitzen upstart
undsystemd
zwar eine Option zum automatischen Neustart eines Programms, die gleiche Funktionalität in init
zu benutzen erfordert aber das Verändern der Konfigurationsdatei des initd
.
Für den Eigenbedarf nutze ich selbst seit einiger Zeit supervisor
zur Lösung dieses Problems. Auf http://supervisord.org finden Sie sowohl das Programm selbst als auch die Dokumentation dazu. Bei den meisten Linux-Distributionen gibt es aber schon Pakete dafür in den Repositories. Supervisor wird bei Systemstart von init oder einer der Alternativen automatisch gestartet. Um das eigene Programm damit zu betreiben muss es in der Konfiguration des supervisor bekannt gemacht werden.
Sollten Sie sich nicht sicher sein, ob Ihr Benutzer über die notwendigen Rechte verfügt, können Sie zu Beginn einer jeden SSH-Session das folgende Kommando ausführen:
sudo -i
Nach Ausführung des Kommandos erhalten Sie weiterführende (Root-) Berechtigungen ohne das Kommando „sudo“ jedem Befehl auf der Kommandozeile voranstellen zu müssen.
Als Beispiel habe ich hier eine Webapplikation in Python geschrieben, erstellt mit dem bottle Framework (http://bottlepy.org). Da dies kein Tutorial zur Webprogrammierung sein soll, ist das Programm sehr einfach.
1 from bottle import route, run
2
3 @route('/')
4 def index():
5 return 'Hello World'
6
7 run(host='0.0.0.0', port=8080)
Dieses Programm startet einen Webserver auf Port 8080 und zeigt ‚Hello World‘ an, wenn man mit einem Webbrowser darauf zugreift. Das Programm wird in der Datei app.py
gespeichert und anschließen mit python app.py
ausgeführt. Es läuft dann bis es manuell beendet wird oder abstürzt. Dies ist ein guter Zeitpunkt um die Konfiguration von Supervisor durchzuführen damit dieser unser Programm ausführt. Supervisor stellt ein Kommandozeilenprogramm bereit, mit dem der aktuelle Status abgerufen werden kann bzw. konfigurierte Programme gestartet oder gestoppt werden können. Der Aufruf von supervisorctl status
zeigt uns… nichts, denn wir haben noch keine Einstellung vorgenommen. Wir legen eine Datei hello.conf
an und speichern sie in /etc/supervisor/conf.d/
ab. Diese enthält die nötigen Parameter damit Supervisor unser Programm steuern kann. Die einfachste Konfiguration enthält einen Namen für unser Programm, das Kommando, das ausgeführt werden soll und einen Benutzernamen unter dem das Programm ausgeführt werden soll. Wird der Benutzername weggelassen, wird das Programm als root ausgeführt – in den meisten Fällen ein unnötiges Sicherheitsrisiko.
[program:hello]
command=/usr/bin/python /home/markus/app.py
user=markus
Die Pfade sind hier bewusst absolut angegeben. Nachdem die Datei gespeichert wurde, können wir sie von supervisor einlesen lassen, in dem wir das Kommando supervisorctl reread
ausführen. Wenn alles richtig eingegeben ist, dann sollte uns die Ausgabe dieses Kommandos zeigen, dass jetzt ein neues Programm verfügbar ist:
# supervisorctl reread
hello: available
Dieses Programm können wir nun starten:
# supervisorctl start hello
hello: started
Wir prüfen nun nochmals den Status:
# supervisorctl status
hello RUNNING pid 32675, uptime 0:00:46
Wie man hier sehen kann, läuft unser Programm. Es wird außerdem die PID und die Zeit seit dem Start angezeigt. Wir simulieren nun einen Absturz indem wir das Programm beenden und prüfen ob Supervisor wie gewollt einen Neustart durchführt:
# kill -9 32675
# supervisorctl status
hello RUNNING pid 32686, uptime 0:00:04
Die supervisor Website enthält noch wesentlich mehr Information über mögliche Parameter für Programme oder die Konfiguration von supervisor selbst. Es ist z.B. auch möglich, Protokolldateien für die Programme anzulegen und diese automatisch zu rotieren, wenn sie eine bestimmte Größe überschreiten. Weitere Details gibt es hier: http://supervisord.org/configuration.html. Endlich gibt es keinen Grund mehr, seine Applikationen in einer screen-Sitzung laufen zu lassen… 😉