Linux-Systemd erklärt: Dienste steuern wie ein Profi

Systemd ist seit über einem Jahrzehnt der Standard-Init-System auf den meisten Linux-Distributionen – Debian, Ubuntu, Arch, Fedora, openSUSE. Es startet Dienste, überwacht sie, verwaltet Logs und steuert den Bootvorgang. Dieser Artikel erklärt die wichtigsten Konzepte und Befehle, damit Dienste zuverlässig laufen und Fehler schnell gefunden werden.

Die Grundidee: Units

Systemd verwaltet „Units". Die wichtigsten Typen:

  • Service-Units (.service) – laufende Dienste (z.B. nginx.service).
  • Timer-Units (.timer) – zeitgesteuerte Aufgaben, der moderne Cron-Ersatz.
  • Socket-Units (.socket) – lauschen auf Ports und starten Dienste bei Bedarf.
  • Mount/Path-Units – Dateisysteme und Datei-Events.

Der zentrale Befehl ist systemctl. Die wichtigsten Kommandos:

systemctl status nginx        # Status + letzte Logzeilen
systemctl start nginx         # Dienst starten
systemctl stop nginx          # Dienst stoppen
systemctl restart nginx       # Neustart (nach Config-Änderung)
systemctl enable nginx        # Autostart beim Boot aktivieren
systemctl disable nginx       # Autostart deaktivieren
systemctl reload nginx        # Config neu laden (ohne Neustart)
systemctl list-units --type=service --state=running

Praxis-Regel: enable --now nginx startet und aktiviert den Autostart in einem Schritt.

Eine eigene Service-Unit schreiben

Eigene Dienste gehören nach /etc/systemd/system/. Beispiel /etc/systemd/system/mein-dienst.service:

[Unit]
Description=Mein eigener Dienst
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=appuser
WorkingDirectory=/opt/mein-dienst
ExecStart=/usr/bin/python3 /opt/mein-dienst/main.py
Restart=on-failure
RestartSec=5
Environment=PYTHONUNBUFFERED=1

[Install]
WantedBy=multi-user.target

Erklärung der wichtigsten Zeilen:

  • After/Wants: Der Dienst startet erst, wenn das Netzwerk oben ist.
  • User: Dienst läuft mit eingeschränkten Rechten – nie als root, wenn es nicht nötig ist.
  • Restart=on-failure: Bei Absturz automatisch neu starten – die wichtigste Zeile für Zuverlässigkeit.
  • WantedBy=multi-user.target: Autostart im normalen Mehrbenutzer-Modus.

Aktivieren:

sudo systemctl daemon-reload
sudo systemctl enable --now mein-dienst
systemctl status mein-dienst

Logs ansehen: journalctl

Systemd sammelt alle Logs zentral im Journal:

journalctl -u mein-dienst          # Logs eines Dienstes
journalctl -u nginx -f             # live mitverfolgen (-f = follow)
journalctl -u nginx --since "1 hour ago"
journalctl -p err -b               # Fehler seit Boot
journalctl -u nginx -n 50          # letzte 50 Zeilen

Der -u-Filter ist Gold wert: Statt durch Log-Dateien zu greppen, sieht man alle Meldungen eines Dienstes an einer Stelle – inklusive stdout/stderr des Prozesses.

Timer statt Cron

Timer-Units sind der moderne Ersatz für Cron-Jobs – mit Kalender-Syntax und verpasster Ausführung. Beispiel /etc/systemd/system/backup.timer:

[Unit]
Description=Tägliches Backup

[Timer]
OnCalendar=*-*-* 03:30:00
Persistent=true

[Install]
WantedBy=timers.target

Dazu die passende Service-Unit backup.service (ohne [Install]):

[Unit]
Description=Tägliches Backup ausführen

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh

Persistent=true ist der entscheidende Vorteil gegenüber Cron: War der Rechner zur geplanten Zeit aus, läuft der Timer nach dem nächsten Boot nach. Aktivieren:

sudo systemctl enable --now backup.timer
systemctl list-timers

Bootvorgang und Targets

Targets gruppieren Units – vergleichbar mit Runlevels der SysV-Ära. Die wichtigsten:

  • multi-user.target – normaler Mehrbenutzer-Modus (ohne GUI).
  • graphical.target – wie multi-user, plus Desktop.
  • network-online.target – Netzwerk vollständig verfügbar.

Bootzeit analysieren: systemd-analyze zeigt die Gesamtzeit, systemd-analyze blame listet die langsamsten Units. Für gezielte Optimierung: systemd-analyze critical-chain.

Fehlerbehandlung: Der Diagnose-Weg

# 1. Status ansehen (zeigt Fehler und letzte Logs)
systemctl status mein-dienst

# 2. Vollständiges Journal des Dienstes
journalctl -u mein-dienst -n 100 --no-pager

# 3. Syntax der Unit prüfen
systemd-analyze verify /etc/systemd/system/mein-dienst.service

# 4. Wenn nötig: Dienst manuell im Vordergrund starten
sudo -u appuser /usr/bin/python3 /opt/mein-dienst/main.py

Typische Ursachen: falscher Pfad in ExecStart, fehlende Berechtigung für den Dienst-User, oder ein Dienst, der im Vordergrund bleiben muss (Type=simple), aber als Daemon forkt (Type=forking nötig).

Umgebungsvariablen und Konfiguration

Dienste brauchen Konfiguration – aber nicht hart verdrahtet im Skript. Systemd übergibt Umgebungsvariablen sauber:

[Service]
Environment=DB_HOST=localhost
Environment=DB_NAME=app
EnvironmentFile=/etc/mein-dienst.env

Mit EnvironmentFile liegt die Konfiguration als eigene Datei (z.B. /etc/mein-dienst.env, Rechte 600) – ideal für Passwörter und Umgebungs-spezifische Werte. Im Skript liest man sie mit os.environ.get("DB_HOST") (Python) oder $DB_HOST (Shell). Nie Zugangsdaten in die Unit selbst schreiben: Sie ist für alle Benutzer lesbar.

Überwachung des Dienstes einrichten

Ein Dienst, den niemand überwacht, fällt unbemerkt aus. Systemd bietet die Grundlagen:

# Aktivitäts-Check: läuft der Dienst?
systemctl is-active mein-dienst

# Watchdog: Dienst muss regelmäßig "systemd-notify WATCHDOG=1" senden
[Service]
WatchdogSec=30

Für den Alltag reicht meist ein simpler Cron- oder Timer-Check, der den Status prüft und bei Problemen alarmiert:

#!/bin/bash
if ! systemctl is-active --quiet mein-dienst; then
    systemctl restart mein-dienst
    echo "$(date): mein-dienst wurde neu gestartet" >> /var/log/mein-dienst-restarts.log
fi

Professionelles Monitoring (Metriken, Alerting, Dashboards) gehört in die Systemadministration – siehe Monitoring-Grundlagen.

Sicherheit und Härtung

Systemd kann Dienste stark einschränken – Stichwort „Sandboxing":

[Service]
PrivateTmp=true          # eigenes /tmp
ProtectSystem=strict     # / und /usr read-only
ReadWritePaths=/var/lib/mein-dienst
NoNewPrivileges=true     # keine Privilege-Eskalation
RestrictAddressFamilies=AF_INET AF_INET6

Diese Optionen sind kostenloser Sicherheitsgewinn und gehören zu jeder sauberen Härtung – mehr unter Systemadministration und im Artikel zu Linux-Sicherheit.

Fazit

Systemd ist kein „böses Monstrum", sondern ein mächtiges, konsistentes Werkzeug: Units beschreiben, systemctl steuert, Journal liefert Logs, Timer ersetzen Cron. Wer diese vier Bausteine beherrscht, administriert Linux-Dienste souverän. Für Container-Deployments gilt dieselbe Logik eine Ebene höher – siehe Docker-Grundlagen.

Verwandte Artikel: Systemadministration · Bash-Grundlagen · TCP/IP-Grundlagen