systemd-Dienste mit systemctl verwalten
Linux-Dienste mit systemctl starten, stoppen, aktivieren und analysieren. Plus: eigene systemd-Unit schreiben und Logs mit journalctl auswerten.
Auf modernen Ubuntu-Systemen wird fast alles, was im Hintergrund läuft – Webserver, SSH-Daemon, Datenbank, der Cron-Nachfolger, sogar das Einhängen von Dateisystemen –, von systemd verwaltet. Der Befehl, mit dem Sie mit systemd sprechen, heißt systemctl. Eine Handvoll systemctl-Verben zu beherrschen, ist der Unterschied zwischen souveränem Serverbetrieb und Raten, warum ein Dienst nicht startet.
Diese Anleitung ist ein praxisnaher Rundgang durch die Dienstverwaltung mit systemctl unter Ubuntu 24.04 LTS: Dienste starten und stoppen, beim Booten aktivieren, ihren Status lesen, eine eigene Unit-Datei schreiben und Logs mit journalctl auswerten. Jeder Befehl ist kopierfertig und gefahrlos auf einem echten Server auszuführen.
Voraussetzungen
- Ein System mit Ubuntu 24.04 LTS.
- Ein Benutzer mit
sudo-Rechten. - Grundlegende Sicherheit beim Bearbeiten von Dateien im Terminal.
Units verstehen
systemd verwaltet Units. Ein Dienst (ein Hintergrundprozess) ist eine Unit vom Typ .service; daneben gibt es .socket, .timer, .mount und .target. Wenn Sie systemctl status ssh eingeben, ergänzt systemd automatisch die Endung .service. Alle geladenen Dienst-Units auflisten:
systemctl list-units --type=serviceAlle installierten Units samt Boot-Verhalten anzeigen:
systemctl list-unit-files --type=serviceDen Dienststatus prüfen
Der meistgenutzte Befehl. Er zeigt, ob ein Dienst läuft, dessen Haupt-PID, Speicherverbrauch und die letzten Logzeilen:
systemctl status ssh● ssh.service - OpenBSD Secure Shell server
Loaded: loaded (/usr/lib/systemd/system/ssh.service; enabled; preset: enabled)
Active: active (running) since Sat 2026-06-20 09:12:03 UTC; 2h 4min ago
Main PID: 812 (sshd)
Memory: 5.2MZwei Begriffe sind hier entscheidend. active (running) nennt den aktuellen Zustand. enabled bedeutet, dass der Dienst beim nächsten Booten startet. Beides ist unabhängig: Ein Dienst kann jetzt laufen, aber beim Boot deaktiviert sein – und umgekehrt.
Für Skripte fragen Sie nur den aktiven Zustand ab, was einen nützlichen Exit-Code liefert:
systemctl is-active ssh
systemctl is-enabled sshStarten, stoppen und neu starten
Diese Befehle ändern den aktuellen Laufzeitzustand und wirken sofort:
sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginxWenn Sie die Konfiguration eines Dienstes ändern, ist reload dem restart vorzuziehen, sofern der Dienst es unterstützt – ein Reload liest die Konfiguration neu ein, ohne Verbindungen zu kappen:
sudo systemctl reload nginxSind Sie unsicher, ob ein Dienst neu laden kann, trifft reload-or-restart die richtige Wahl:
sudo systemctl reload-or-restart nginxBeim Booten aktivieren und deaktivieren
enable erstellt die Symlinks, die einen Dienst beim Booten starten lassen; disable entfernt sie. Keiner der beiden ändert den aktuellen Zustand. Um beides auf einmal zu erledigen, hängen Sie --now an:
sudo systemctl enable --now nginx
sudo systemctl disable --now nginxDamit ein Dienst nie gestartet werden kann – auch nicht als Abhängigkeit einer anderen Unit –, maskieren Sie ihn. Das verlinkt ihn nach /dev/null:
sudo systemctl mask nginx
sudo systemctl unmask nginxEine eigene systemd-Unit schreiben
Angenommen, Sie haben eine kleine Python-Anwendung unter /opt/myapp/app.py, die als verwalteter Dienst laufen soll – bei einem Absturz automatisch neu gestartet, beim Booten aktiviert. Legen Sie eine Unit-Datei an:
sudo nano /etc/systemd/system/myapp.serviceEigene Units gehören nach /etc/systemd/system/; dieses Verzeichnis ist für vom Administrator definierte Units gedacht und überschreibt paketierte. Fügen Sie ein:
[Unit] Description=My Python Application After=network.target[Service] Type=simple User=www-data WorkingDirectory=/opt/myapp ExecStart=/usr/bin/python3 /opt/myapp/app.py Restart=on-failure RestartSec=5
[Install] WantedBy=multi-user.target
Die drei Abschnitte haben klar getrennte Aufgaben. [Unit] enthält Metadaten und Reihenfolge (After=network.target wartet auf das Netzwerk). [Service] legt fest, wie der Prozess läuft: Type=simple bedeutet, dass der von ExecStart gestartete Prozess der Dienst selbst ist; Restart=on-failure startet ihn nach einem Fehler-Exit neu. [Install] bestimmt das Verhalten bei enable – WantedBy=multi-user.target bindet ihn an den normalen Mehrbenutzer-Boot.
Die Unit laden und verwalten
Nach jedem Anlegen oder Ändern einer Unit-Datei laden Sie den systemd-Manager neu, damit er die Dateien von der Festplatte neu einliest:
sudo systemctl daemon-reloadNun starten und aktivieren Sie den Dienst:
sudo systemctl enable --now myapp.servicePrüfen, ob er hochkam:
systemctl status myapp.serviceLogs mit journalctl lesen
systemd fängt stdout und stderr jedes Dienstes im Journal ab. Die Logs eines bestimmten Dienstes lesen Sie so:
journalctl -u myapp.serviceDie nützlichsten Optionen im Alltag:
journalctl -u myapp.service -f # live verfolgen, wie tail -f
journalctl -u myapp.service -n 50 # letzte 50 Zeilen
journalctl -u myapp.service --since '10 min ago'
journalctl -u myapp.service -p err # nur Fehlerpriorität und schlimmerNur die Logs des aktuellen Boots anzeigen:
journalctl -u myapp.service -bÜberprüfung
Weisen Sie nach, dass der automatische Neustart funktioniert. Ermitteln Sie die Haupt-PID, beenden Sie sie und prüfen Sie, ob sich der Dienst erholt:
systemctl show -p MainPID myapp.service
sudo kill <PID>
systemctl status myapp.serviceInnerhalb von fünf Sekunden (RestartSec=5) sollte systemd den Prozess mit neuer PID neu starten, und das Journal hält den Neustart fest. Das bestätigt, dass sowohl Ihre Unit-Datei als auch die Neustart-Richtlinie korrekt sind.
Häufige Stolperfallen und Fehlerbehebung
- daemon-reload vergessen. Nach dem Bearbeiten einer Unit-Datei behält systemd die alte Version im Cache, bis Sie
sudo systemctl daemon-reloadausführen. Werden Ihre Änderungen ignoriert, liegt es meist daran. - enabled mit active verwechseln.
enablebetrifft nur den Boot; es startet den Dienst nicht sofort. Mit--nowerledigen Sie beides. - Falscher Type=. Forkt Ihr Programm in den Hintergrund, hält
Type=simplees für beendet. Nutzen SieType=forking(mit PIDFile) oder lassen Sie den Prozess besser im Vordergrund laufen. - Dienst scheitert sofort. Führen Sie
systemctl statusundjournalctl -xeu myapp.serviceaus – das-xergänzt erklärende Hinweise. Häufige Ursachen sind ein falscherExecStart-Pfad oder einUser=, dem die Rechte amWorkingDirectoryfehlen. - Paketierte Units direkt bearbeiten. Bearbeiten Sie keine Dateien unter
/usr/lib/systemd/system/; Paket-Updates überschreiben sie. Erzeugen Sie stattdessen mitsudo systemctl edit dienstnameein Drop-in-Override.
Fazit
Mit start, stop, enable, status, einer eigenen Unit-Datei und journalctl verwalten Sie den vollständigen Lebenszyklus jedes Dienstes auf einem Ubuntu-Server. Dieselben Befehle funktionieren auf jeder systemd-basierten Distribution identisch – das Wissen ist überall übertragbar.
Sind Ihre Dienste als Units definiert, folgt als Nächstes das Planen wiederkehrender Aufgaben – vergleichen Sie Cron und systemd-Timer in unserer Anleitung zum Planen von Aufgaben mit Cron unter Linux, und stellen Sie einen Dienst sicher ins Internet mit einem Nginx-Reverse-Proxy. Dutzende Dienste über eine Server-Flotte hinweg gesund zu halten, ist genau das, was eine verwaltete Plattform automatisiert: clouditiv überwacht Unit-Health, Neustarts und Ressourcengrenzen im Rahmen seines Monitorings – damit Sie nicht um 3 Uhr nachts journalctl lesen müssen.