systemd Service Unit Beispiel
Achtung!
Die Verwendung dieses Howto geschieht auf eigene Gefahr. Bei Problemen mit der Anleitung melde dies bitte in der dazugehörigen Diskussion und wende dich zusätzlich an den Verfasser des Howtos.
Hinweis:
Diese Howto-Anleitung wurde zuletzt von noisefloor am 12.2.2021 unter Ubuntu 18.04 erfolgreich getestet.
Zum Verständnis dieses Artikels sind folgende Seiten hilfreich:
Im folgenden wird anhand eines Beispiels gezeigt, wie man eine eigene Service Unit für systemd anlegt und aktiviert.
Das Programm, welches ausgeführt werden soll, ist ein simpler, in Python geschriebener Webserver, welcher nichts anderes macht, als auf localhost und Port 8000 zu lauschen und beim Aufruf der Adresse http://127.0.0.1:8000
"Hello World" und die aktuelle Uhrzeit auszugeben.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #!/usr/bin/env python3 from wsgiref.simple_server import make_server from datetime import datetime def hello_world_app(environ, start_response): status = '200 OK' headers = [('Content-type', 'text/plain; charset=utf-8')] start_response(status, headers) text = 'Hello World @ {}'.format(datetime.now()) return [text.encode('utf-8')] httpd = make_server('', 8000, hello_world_app) httpd.serve_forever() |
Der Code wird z.B. im Homeverzeichnis unter /home/BENUTZER/code/simple_wsgi_server.py gespeichert. Anschließend muss die Datei noch ausführbar gemacht werden[4].
.service Datei anlegen¶
Als erstes muss eine .service Datei unter /etc/systemd/system angelegt werden, z.B. mit dem Dateinamen wsgiserver.service. Diese Datei editiert man dann mit einem Editor mit Root-Rechten[2][3] und fügt folgenden Inhalt ein:
[Unit] Description=Simple WSGI Server [Service] Type=simple ExecStart=/home/BENUTZER/code/simple_wsgi_server.py [Install] WantedBy=multi-user.target
Service Unit aktivieren¶
Jetzt muss die Service Unit noch aktiviert werden[1][3]:
sudo systemctl enable wsgiserver.service
Anschließend kann die Unit gestartet werden:
sudo systemctl start wsgiserver.service
Wer jetzt auf dem Rechner im Webbrowser die Adresse http://127.0.0.1:8000
aufruft, der sollte mit einem "Hello World" plus Datum und Uhrzeit begrüßt werden.
Modifikation¶
Benutzer ändern¶
Da in der .service Datei kein Nutzer angegeben ist, wird das Python-Skript von Root ausgeführt. Um den Nutzer zu ändern, ergänzt man die Datei wsgiserver.service in der Sektion "[Service]" um die Zeile
User=www-data
Dann läuft das Skript mit den Rechten des Nutzers www-data. Natürlich kann man hier auch jeden anderen Benutzer angeben, der auf dem System existiert.
Wichtig ist dabei, dass dieser Nutzer auch die nötigen Rechte hat, die Datei auszuführen. Für das obige Beispiel des einfachen Servers würde das Ausführungsrecht benötigt.
Möchte man für die Python-Datei nur das Leserecht für alle Nutzer einräumen, dann wäre folgende Änderung an der .service Datei notwendig:
... [Service] ... ExecStart=/usr/bin/python3 /home/BENUTZER/code/simple_wsgi_server.py ...
Da der Pfad zum Python3 Interpreter mit angegeben wird, muss die Datei simple_wsgi_server.py nicht (mehr) ausführbar sein.
Server im gesamten Netzwerk erreichbar machen¶
Der Server aus dem obigen Beispiel läuft nur auf localhost
und ist somit für andere Rechner im selben Netzwerk nicht erreichbar. Wer den Webserver von anderen Clients im Netzerreichen möchte, muss die letzte Zeile im Python-Skript wie folgt ändern:
1 | httpd = make_server('0.0.0.0', 8000, hello_world_app) |
Damit läuft der Server für alle IP-Addresse.
Und da der Server jetzt über das Netzwerk erreichbar ist, sollt er natürlich nur gestartet werden, wenn das Netzwerk auch verfügbar ist. Um das zu erreichen, fügt man in der .service-Datei in der Sektion "[Unit]" noch folgende Zeile ein:
After=network.target
systemd prüft so vor Starten des Servers, ob das Netzwerk vorhanden / bereit ist.
Zusätzliche Befehl vor und nach dem Start ausführen¶
Das Python Serverskript benötigt keine zusätzlichen Befehle, die vor oder nach dem Start ausgeführt werden müssten. Andere / komplexere Skripte / Programme, benötigen dies aber vielleicht doch, z.B. zum Löschen von alten Daten etc.
Um zusätzliche Befehle auszuführen, hinterlegt man in der Sektion "[Service]" die Schlüssel ExecStartPre
und / oder ExecStartPost
Würde man die Sektion um z.B. um die Zeile
ExecStartPost=/bin/echo "Server gestartet"
erweitern, so würde der Eintrag "Server gestartet" zusätzlich in die zentrale Logdatei geschrieben, nachdem der Server erfolgreich gestartet wurde.
Hinweis: Bei realen Applikationen ist diese Art von Logging überflüssig, da systemd sowieso in die zentrale Logdatei loggt, dass ein Service gestartet wurde. Für dieses Beispiel sieht der Logeintrag z.B so aus.
Jan 16 17:32:31 noisefloor-xubuntu systemd[1]: Started Simple WSGI Server
Links¶
systemd/Service Units - Wikiartikel zum Thema Aufbau von Service Units unter systemd