Start, Stop, Status und Logs im Griff
Wer systemd-Services nur über Trial and Error steuert, verliert bei Ausfällen wertvolle Zeit im Produktivbetrieb. Mit systemctl startet, stoppt und überwacht man Dienste zuverlässig, liest Statusausgaben korrekt und erkennt Zustände wie failed oder activating sofort und ohne Rätselraten. journalctl liefert dazu die passenden, gefilterten Logs für schnelle Fehlersuche in produktiven Linux-Umgebungen und Magento-Deployments.
Inhaltsverzeichnis
- 1. Warum systemd-Service-Management zum Admin-Alltag gehört
- 2. systemctl-Grundkommandos: start, stop, restart
- 3. Service-Status richtig lesen: Active, Loaded, Main PID
- 4. enable, disable und die Rolle der Symlinks
- 5. Logs analysieren mit journalctl -u
- 6. Service-Zustände verstehen: failed, activating, dead
- 7. Dependencies, Timeouts und Restart-Policies
- 8. Eigene Unit-Dateien für Cronjobs und Queues
- 9. systemctl im direkten Vergleich zu SysVinit
- 10. Zusammenfassung
- 11. FAQ
1. Warum systemd-Service-Management zum Admin-Alltag gehört
systemd ist seit Jahren der Init-Prozess und Service-Manager fast aller gängigen Linux-Distributionen: Ubuntu, Debian, RHEL, CentOS, Fedora, SUSE. Wer einen Server administriert oder Anwendungen wie PHP-FPM, Nginx, MySQL, Varnish oder eigene Magento-Queue-Consumer betreibt, kommt an systemctl nicht vorbei. Anders als beim alten SysVinit-System mit seinen Shell-Skripten unter /etc/init.d/ bietet systemd eine einheitliche, deklarative Schnittstelle für alle Dienste, unabhängig davon, ob sie beim Booten automatisch starten, von anderen Diensten abhängen oder bei einem Absturz automatisch neu gestartet werden sollen.
Der praktische Nutzen zeigt sich vor allem im Fehlerfall: Ein Shop reagiert nicht mehr, ein Consumer verarbeitet keine Nachrichten mehr, ein Cronjob läuft nicht. In all diesen Situationen ist der erste Schritt fast immer derselbe: den betroffenen Service über systemctl status prüfen, die letzten Logzeilen einsehen und den Zustand korrekt einordnen. Wer diesen Ablauf beherrscht, spart in Incident-Situationen wertvolle Minuten, statt Prozesslisten manuell zu durchsuchen oder Logdateien blind zu tailen.
2. systemctl-Grundkommandos: start, stop, restart
Die vier Grundkommandos für den täglichen Betrieb sind systemctl start, systemctl stop, systemctl restart und systemctl reload. start startet einen Dienst, der aktuell nicht läuft, stop beendet ihn kontrolliert über das im Unit-File definierte Signal, meist SIGTERM mit anschließendem SIGKILL nach Ablauf einer Timeout-Frist. restart ist funktional ein stop gefolgt von einem start und damit immer mit einer kurzen Downtime verbunden. reload dagegen signalisiert dem laufenden Prozess, seine Konfiguration neu einzulesen, ohne den Prozess selbst zu beenden, was bei Nginx oder PHP-FPM Verbindungsabbrüche vermeidet.
Für Automatisierung ist der Exit-Code jedes Kommandos entscheidend: systemctl restart gibt bei Erfolg 0 zurück, bei Fehlschlag einen Wert ungleich 0, was sich in Deploy-Skripten direkt mit set -e prüfen lässt. Wichtig ist außerdem der Unterschied zwischen systemctl start service und systemctl start service.service: Wird kein Suffix angegeben, ergänzt systemctl automatisch .service, bei Timern, Sockets oder Mount-Units muss das Suffix jedoch explizit angegeben werden, da sonst versehentlich die falsche Unit angesprochen wird.
# Start, stop and restart a single service
sudo systemctl start php8.3-fpm
sudo systemctl stop php8.3-fpm
sudo systemctl restart php8.3-fpm
# Reload config without downtime (only if the service supports it)
sudo systemctl reload nginx
# Combination of reload and restart as a safe fallback
sudo systemctl reload-or-restart nginx
# Check the exit code, e.g. inside a deploy script
if ! sudo systemctl restart php8.3-fpm; then
echo "[ERROR] php8.3-fpm restart failed" >&2
exit 1
fi
# Manage several services in a single call
sudo systemctl restart nginx php8.3-fpm supervisor
3. Service-Status richtig lesen: Active, Loaded, Main PID
systemctl status service.service liefert deutlich mehr Information als ein einfacher "läuft" oder "läuft nicht" Zustand. Die Zeile Loaded: zeigt, ob die Unit-Datei gefunden und geparst wurde, sowie den aktuellen Enabled-Status. Die Zeile Active: ist die wichtigste: Sie zeigt den kombinierten Zustand aus High-Level-Status (active, inactive, failed) und Low-Level-Detail in Klammern (running, exited, dead) sowie die Zeitdauer seit dem letzten Zustandswechsel. Ein Dienst kann active (running) sein, wenn er dauerhaft laufen soll, oder active (exited), wenn es sich um einen Oneshot-Dienst handelt, der einmalig etwas ausführt und dann beendet, ohne dass das ein Fehler ist.
Die Zeile Main PID: zeigt die Prozess-ID des Hauptprozesses zusammen mit dem tatsächlich laufenden Befehl, was hilft, den Service in ps oder htop wiederzufinden. Darunter listet systemd die aktuelle cgroup-Hierarchie mit allen Kindprozessen, was bei Diensten mit mehreren Worker-Prozessen wie PHP-FPM oder Supervisor besonders nützlich ist. Am Ende der Ausgabe erscheinen automatisch die letzten Logzeilen aus dem Journal, sodass man für eine erste Diagnose oft gar nicht zu journalctl wechseln muss.
$ systemctl status nginx.service
● nginx.service - A high performance web server and reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2026-07-12 08:14:03 UTC; 2h 11min ago
Docs: man:nginx(8)
Process: 1042 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
Main PID: 1055 (nginx)
Tasks: 5 (limit: 4915)
Memory: 12.4M
CPU: 891ms
CGroup: /system.slice/nginx.service
├─1055 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
├─1056 nginx: worker process
└─1057 nginx: worker process
Jul 12 08:14:03 web01 systemd[1]: Starting A high performance web server...
Jul 12 08:14:03 web01 systemd[1]: Started A high performance web server and reverse proxy server.
4. enable, disable und die Rolle der Symlinks
Ein Service kann laufen, ohne beim nächsten Boot automatisch zu starten, und umgekehrt beim Boot vorgesehen sein, ohne aktuell aktiv zu sein. systemctl start und systemctl enable sind also unabhängige Schalter für zwei verschiedene Fragen: läuft der Dienst jetzt, und soll er beim Systemstart automatisch starten. systemctl enable erzeugt technisch einen Symlink von der Unit-Datei in das passende .wants-Verzeichnis des konfigurierten Targets, meist /etc/systemd/system/multi-user.target.wants/. systemctl disable entfernt genau diesen Symlink wieder, ohne den laufenden Prozess zu beeinflussen.
Für Deploy-Automatisierung ist systemctl enable --now redis-server das praktische Kombi-Kommando, das den Symlink setzt und den Dienst im selben Schritt startet, während systemctl disable redis-server den Symlink wieder entfernt, ohne den laufenden Prozess zu stoppen. Ob ein Dienst aktuell für den Autostart aktiviert ist, zeigt systemctl is-enabled redis-server, den Laufzustand liefert systemctl is-active redis-server. Nach jeder Änderung an einer Unit-Datei selbst, etwa nach dem Anpassen von ExecStart oder Restart, muss systemctl daemon-reload ausgeführt werden, damit systemd die Datei neu einliest. Wird dieser Schritt vergessen, arbeitet systemd mit der alten, im Speicher zwischengespeicherten Definition weiter, was zu verwirrenden Situationen führt, in denen eine Konfigurationsänderung scheinbar keine Wirkung zeigt. Einen Überblick über alle für den Autostart aktivierten Dienste liefert systemctl list-unit-files --state=enabled.
5. Logs analysieren mit journalctl -u
journalctl ist das zentrale Werkzeug, um Logs zu lesen, die systemd im binären, strukturierten systemd-journal speichert. Der wichtigste Filter für den Alltag ist -u, der die Ausgabe auf eine einzelne Unit beschränkt: journalctl -u nginx.service zeigt ausschließlich Logeinträge dieses Dienstes, unabhängig davon, ob sie über stdout, stderr oder das native systemd-Logging-API geschrieben wurden. Das ersetzt das mühsame Grep-Filtern über gemeinsame Logdateien, in denen mehrere Dienste ihre Ausgabe vermischen.
Die Flag -f folgt dem Log live, ähnlich wie tail -f, und ist der Standardweg, um während eines Deployments oder Restarts mitzulesen. Mit --since und --until lässt sich der Zeitraum präzise eingrenzen, wobei relative Angaben wie "1 hour ago" und absolute Zeitstempel gleichermaßen funktionieren. Für strukturierte Weiterverarbeitung liefert -o json jede Logzeile als eigenständiges JSON-Objekt mit allen Metadaten wie PID, Priorität und Boot-ID, was sich hervorragend in Log-Aggregatoren wie Fluentd oder Logstash einspeisen lässt. -p err filtert zusätzlich nach Priorität und zeigt ausschließlich Fehler und kritischere Meldungen.
# Follow a service's log live
journalctl -u php8.3-fpm.service -f
# Only error priority and higher, from the last hour
journalctl -u php8.3-fpm.service -p err --since "1 hour ago"
# Logs since the last boot, with precise local timestamps
journalctl -u nginx.service -b --output=short-precise
# Logs from several units, merged and sorted by time
journalctl -u nginx.service -u php8.3-fpm.service --since today
# Cap journal size to keep disk usage under control
sudo journalctl --vacuum-size=500M
sudo journalctl --vacuum-time=14d
6. Service-Zustände verstehen: failed, activating, dead
Der Zustand failed bedeutet, dass der Dienst gestartet wurde, aber mit einem Fehler beendet wurde oder ein ExecStart-Befehl selbst fehlgeschlagen ist. Ein failed-Zustand bleibt bestehen, bis er entweder manuell mit systemctl reset-failed zurückgesetzt oder der Dienst erfolgreich neu gestartet wird. Der Zustand activating ist bei den meisten Diensten ein kurzer Übergangszustand während des Starts, kann bei fehlerhaft konfigurierten Diensten mit langsamen Health-Checks aber minutenlang stehen bleiben, insbesondere bei Diensten vom Typ notify, die auf ein Bereitschaftssignal vom Prozess selbst warten.
dead beschreibt schlicht einen gestoppten Dienst ohne Fehler, etwa nach einem geplanten systemctl stop. Der Unterschied zwischen inactive und failed ist entscheidend für Monitoring-Systeme: inactive ist meist ein gewollter Zustand, failed ist immer ein Alarmsignal. systemctl --failed listet serverweit alle Units im Fehlerzustand auf und ist damit der schnellste erste Befehl bei einer allgemeinen Störungsmeldung, bevor man einzelne Dienste gezielt prüft. Ein failed-Zustand lässt sich gezielt mit systemctl reset-failed myapp-worker.service zurücksetzen, und in Skripten kann der aktuelle Zustand direkt über systemctl is-active myapp-worker.service abgefragt und ausgewertet werden.
7. Dependencies, Timeouts und Restart-Policies
systemd modelliert Abhängigkeiten zwischen Diensten explizit über Direktiven wie Requires=, Wants= und After=. Requires= erzwingt, dass die abhängige Unit ebenfalls gestartet werden muss, andernfalls scheitert der Start; schlägt die Abhängigkeit später fehl, wird die abhängige Unit mit gestoppt. Wants= ist die schwächere, empfohlene Variante für die meisten Anwendungsfälle: Sie versucht, die andere Unit mitzustarten, scheitert aber nicht, wenn das nicht gelingt. After= und Before= steuern ausschließlich die Startreihenfolge, ohne selbst eine Abhängigkeit im Sinne von "muss laufen" zu erzeugen, weshalb Wants= und After= in der Praxis meist gemeinsam auftreten.
Für Ausfallsicherheit ist die Restart=-Direktive entscheidend: Restart=on-failure startet den Dienst nur bei einem Fehlerzustand automatisch neu, Restart=always auch nach einem regulären Exit-Code 0. RestartSec= definiert die Wartezeit zwischen Neustartversuchen, während StartLimitBurst= und StartLimitIntervalSec= verhindern, dass ein dauerhaft abstürzender Dienst systemd in eine Neustart-Endlosschleife treibt, die den Server unter Last setzt.
8. Eigene Unit-Dateien für Cronjobs und Queues
Für langlebige Hintergrundprozesse wie Magento-Message-Queue-Consumer ist eine eigene Unit-Datei robuster als ein Cronjob mit nohup oder ein manuell gestarteter screen. Eigene Unit-Dateien gehören nach /etc/systemd/system/, nicht in /lib/systemd/system/, das für Paket-Manager reserviert bleibt. Der [Service]-Block definiert mit Type=simple den Standardfall eines im Vordergrund laufenden Prozesses, User= und Group= stellen sicher, dass der Consumer nicht versehentlich als root läuft, und WorkingDirectory= setzt das Arbeitsverzeichnis korrekt, bevor der Befehl ausgeführt wird.
Nach dem Anlegen einer neuen Unit-Datei ist die Reihenfolge immer gleich: daemon-reload, dann enable --now. Für Consumer, die zwischenzeitlich abstürzen können, etwa durch einen OutOfMemory-Kill des Kernels, sorgt Restart=always in Kombination mit RestartSec=5 für eine automatische Wiederaufnahme, ohne dass ein zusätzliches Supervisor-Tool wie Supervisord nötig wird.
# /etc/systemd/system/magento-consumer-inventory.service
[Unit]
Description=Magento Inventory Reservation Queue Consumer
After=network.target mysql.service rabbitmq-server.service
Wants=rabbitmq-server.service
[Service]
Type=simple
User=deploy
Group=deploy
WorkingDirectory=/var/www/magento
ExecStart=/usr/bin/php bin/magento queue:consumers:start inventory.reservation.updateSalabilityAfterOrderPlacement --max-messages=1000
Restart=always
RestartSec=5
StartLimitIntervalSec=60
StartLimitBurst=5
TimeoutStopSec=30
StandardOutput=journal
StandardError=journal
SyslogIdentifier=magento-consumer-inventory
[Install]
WantedBy=multi-user.target
Für Automatisierung und CI/CD ist es hilfreich zu wissen, dass sich der Zustand einer Unit auch maschinenlesbar auslesen lässt: systemctl show magento-consumer-inventory.service --output=json -p ExecMainStatus -p Result -p ActiveState -p SubState -p MainPID liefert genau diese Felder als JSON-Objekt, das sich direkt in Monitoring-Skripte oder Deploy-Pipelines einbinden lässt, ohne die textuelle Statusausgabe parsen zu müssen.
# Ansible task: deploy a systemd unit and ensure its target state
- name: Deploy magento consumer unit file
ansible.builtin.template:
src: magento-consumer-inventory.service.j2
dest: /etc/systemd/system/magento-consumer-inventory.service
mode: "0644"
notify: reload systemd
- name: Ensure consumer service is enabled and running
ansible.builtin.systemd:
name: magento-consumer-inventory.service
enabled: true
state: started
daemon_reload: true
handlers:
- name: reload systemd
ansible.builtin.systemd:
daemon_reload: true
Mironsoft
Server-Administration, Deployment-Automatisierung und systemd-Setups
Zuverlässige systemd-Services für euren Stack?
Wir richten Unit-Dateien für Queue-Consumer, Cronjobs und Hintergrundprozesse ein, konfigurieren Restart-Policies und Dependencies korrekt und sorgen für ein Monitoring, das failed-Zustände sofort meldet.
Unit-Setup
Robuste Unit-Dateien für Consumer, Worker und Cronjobs erstellen
Monitoring
Alerting auf failed-Zustände via journalctl und externe Tools
Deploy-Automatisierung
Ansible-Rollen für systemd-Deployments in CI/CD-Pipelines
9. systemctl im direkten Vergleich zu SysVinit
Wer von klassischen init.d-Skripten auf systemd umsteigt, sucht meist nach dem direkten Äquivalent eines gewohnten Befehls. Die folgende Tabelle stellt die wichtigsten alten Muster den modernen systemctl-Äquivalenten gegenüber.
| Aufgabe | Alter Weg (SysVinit) | systemd-Äquivalent | Vorteil |
|---|---|---|---|
| Dienst starten | service apache2 start |
systemctl start apache2 |
Einheitliches Interface für alle Dienste |
| Autostart aktivieren | update-rc.d apache2 defaults |
systemctl enable apache2 |
Symlink-basiert, sofort nachvollziehbar |
| Logs einsehen | tail -f /var/log/apache2/error.log |
journalctl -u apache2 -f |
Strukturiert, mit Metadaten und Filtern |
| Status prüfen | ps aux | grep apache2 |
systemctl status apache2 |
Zeigt PID, Speicher, Zustand und Logs |
| Automatischer Neustart | Eigenes Watchdog-Skript per Cron | Restart=on-failure in Unit-Datei |
Kein Zusatz-Tooling nötig |
Der Umstieg lohnt sich vor allem, weil systemd eine konsistente Sicht auf alle Dienste liefert, egal ob es sich um einen Paket-installierten Webserver oder eine selbst geschriebene Unit für einen Magento-Consumer handelt. Wer systemctl und journalctl beherrscht, braucht für die überwiegende Mehrheit der Diagnose- und Betriebsaufgaben kein zusätzliches Tooling mehr.
10. Zusammenfassung
Das Verwalten von systemd-Services reduziert sich im Kern auf wenige, klar definierte Befehle: systemctl start/stop/restart für den laufenden Zustand, systemctl enable/disable für den Autostart, und systemctl status als erster Anlaufpunkt bei jeder Störung. Die Statusausgabe liefert mit Active:, Loaded: und Main PID: bereits die meisten Informationen für eine erste Diagnose, ohne dass man zusätzliche Tools bemühen muss. journalctl -u ergänzt das um gefilterte, strukturierte Logs, die sich live verfolgen, zeitlich eingrenzen und nach Priorität filtern lassen.
Wer die Bedeutung der Zustände failed, activating und dead korrekt einordnet und eigene Unit-Dateien mit sauberen Restart-Policies und Dependencies schreibt, ersetzt fragile Cron- oder nohup-Konstrukte durch produktionstaugliche, vom Kernel überwachte Prozesse. systemctl --failed als serverweiter Rundumblick und daemon-reload nach jeder Unit-Änderung gehören zu den Befehlen, die in keinem Admin-Alltag fehlen dürfen.
systemd-Services verwalten, Das Wichtigste auf einen Blick
Grundkommandos
systemctl start/stop/restart für den Laufzustand, enable --now für Autostart plus sofortigen Start in einem Schritt.
Status lesen
Active:, Loaded: und Main PID: liefern die zentrale Diagnose direkt in der Statusausgabe.
Logs mit journalctl
journalctl -u service -f zum Live-Verfolgen, -p err und --since zum gezielten Filtern.
Zustände & Policies
systemctl --failed als Rundumblick, Restart=on-failure für automatische Wiederherstellung.