Zum Inhalt springen
Serverküche
Suche

Die Suche wird geladen … (nur in der veröffentlichten Seite verfügbar).

Grundlagen Schwierigkeit: Einsteiger

systemd verstehen: Units, Journal & Timer (statt Cron)

Dienste starten, Logs lesen, Aufgaben planen: Dieser Grundlagen-Guide erklärt systemd an echten Befehlen – inklusive eigenem Dienst und Timer statt Cron.

· 6 Min. Lesezeit ·Dauer: ca. 30 Minuten
Inhaltsverzeichnis

Jeder Dienst auf deinem Server – SSH, Docker, die Firewall – wird von systemd gestartet, überwacht und protokolliert. Wer systemd versteht, kann Ausfälle diagnostizieren, eigene Hintergrundjobs anlegen und geplante Aufgaben sauber automatisieren. Dieser Guide macht dich damit vertraut.

Was bauen wir?

Kein Dienst, sondern das Werkzeug, mit dem alle Dienste laufen: systemd (hier v257 auf Debian 13). Am Ende kannst du Dienste starten, stoppen und beim Booten aktivieren, ihre Logs mit journalctl lesen, einen eigenen Dienst als Unit-Datei anlegen und einen Timer bauen, der Cron ersetzt – mit dem entscheidenden Vorteil, dass er verpasste Läufe nachholen kann.

Voraussetzungen

🍳 Empfehlung Anzeige

VPS 1000 G12

4 vCore · 8 GB RAM · 256 GB NVMe

ab 10,36 €/Monat

Die Befehle sind auf jedem systemd-Linux gleich – jeder Server genügt.

Zu netcup →

💶 5 € Gutschein für netcup-Neukunden:36nc17844976032 (nur Neukunden, keine Domains)

Schritt für Schritt

Schritt 1: Units – das Grundkonzept

systemd verwaltet alles als Units. Die wichtigste Art ist der Service (.service) – ein Hintergrunddienst. Daneben gibt es u. a. Timer (.timer, geplante Ausführung), Sockets und Targets (Gruppen, grob vergleichbar mit Runlevels). Prüfe zuerst, welche Version läuft:

Terminal
systemctl --version
Ausgabe
systemd 257 (257.13-1~deb13u1)

Alle laufenden Dienste zeigt dir systemctl:

Terminal
systemctl list-units --type=service --state=running
Ausgabe
  containerd.service   loaded active running containerd container runtime
  cron.service         loaded active running Regular background program processing daemon
  docker.service       loaded active running Docker Application Container Engine
  fail2ban.service     loaded active running Fail2Ban Service
  ssh.service          loaded active running OpenBSD Secure Shell server

Jede Zeile ist eine Unit mit Ladezustand (loaded), Aktivzustand (active) und Unterzustand (running).

Schritt 2: Dienste steuern

Der wichtigste Befehl ist systemctl status. Er zeigt dir alles über einen Dienst – am Beispiel Docker:

Terminal
systemctl status docker
Ausgabe
● docker.service - Docker Application Container Engine
     Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; preset: enabled)
     Active: active (running) since Sun 2026-07-19 21:34:42 CEST; 4 days ago
   Main PID: 53379 (dockerd)
      Tasks: 93
     Memory: 282.8M (peak: 334.6M)

Zwei Zeilen sind entscheidend: Active: (läuft der Dienst gerade?) und in der Loaded:-Zeile das Wort enabled (startet er beim Booten automatisch?). Das sind zwei unabhängige Dinge – ein Dienst kann laufen, aber nicht beim Boot starten, und umgekehrt. Für Skripte fragst du beides knapp ab:

Terminal
systemctl is-active docker
systemctl is-enabled docker
Ausgabe
active
enabled

Die vier Befehle für den Alltag: systemctl start DIENST (jetzt starten), stop (jetzt anhalten), restart (neu starten, z. B. nach Konfigänderung) und reload (Konfiguration neu einlesen, ohne den Dienst zu unterbrechen – sofern er das unterstützt). Wichtig: start/stop wirken nur bis zum nächsten Reboot. Damit ein Dienst dauerhaft beim Booten startet, brauchst du enable:

Terminal
systemctl enable --now DIENST

enable schaltet den Autostart ein, --now startet den Dienst zusätzlich sofort – so sparst du dir den separaten start.

Schritt 3: Logs lesen mit journalctl

systemd sammelt die Ausgaben aller Dienste zentral im Journal. Statt in verstreuten Log-Dateien zu suchen, fragst du gezielt einen Dienst ab:

Terminal
journalctl -u docker -n 20

-u wählt die Unit, -n 20 zeigt die letzten 20 Zeilen. Die nützlichsten Varianten:

  • journalctl -u DIENST -f – live mitverfolgen (wie tail -f), ideal beim Debuggen.
  • journalctl -u DIENST --since "1 hour ago" – zeitlich eingrenzen.
  • journalctl -p err -b – nur Fehler seit dem letzten Boot (-b = aktueller Boot).

Genau das ist der erste Griff, wenn ein Dienst nicht startet: systemctl status DIENST für den Überblick, dann journalctl -u DIENST für die Details.

Schritt 4: Einen eigenen Dienst anlegen

Jetzt baust du selbst eine Unit. Beispiel: ein Backup-Skript, das systemd ausführen soll. Unit-Dateien für eigene Dienste liegen in /etc/systemd/system/. Lege backup-demo.service an:

INI
[Unit]
Description=Demo-Backup-Job

[Service]
Type=oneshot
ExecStart=/usr/bin/bash -c 'echo "Backup lief am $(date)" >> /var/log/backup-demo.log'

Der Abschnitt [Unit] beschreibt die Unit, [Service] sagt, was laufen soll. Type=oneshot ist der Typ für einmalige Aufgaben, die starten, ihre Arbeit tun und sich beenden (im Gegensatz zu Dauerdiensten wie docker). Nach dem Anlegen einer neuen Unit muss systemd sie einlesen:

Terminal
systemctl daemon-reload
systemctl start backup-demo.service

Prüfe das Ergebnis – oneshot-Dienste stehen nach getaner Arbeit korrekterweise auf inactive (dead):

Terminal
systemctl status backup-demo.service
Ausgabe
○ backup-demo.service - Demo-Backup-Job
     Loaded: loaded (/etc/systemd/system/backup-demo.service; static)
     Active: inactive (dead)

systemd[1]: Starting backup-demo.service - Demo-Backup-Job...
systemd[1]: backup-demo.service: Deactivated successfully.
systemd[1]: Finished backup-demo.service - Demo-Backup-Job.

Schritt 5: Timer statt Cron

Damit der Job regelmäßig läuft, koppelst du ihn an einen Timer – die systemd-Alternative zu Cron. Lege backup-demo.timer an (gleicher Name wie der Service, andere Endung):

INI
[Unit]
Description=Startet den Demo-Backup täglich

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

[Install]
WantedBy=timers.target

OnCalendar bestimmt den Zeitplan (hier: täglich um 03:00 Uhr). Persistent=true ist der entscheidende Vorteil gegenüber Cron: War der Server zur geplanten Zeit aus, holt systemd den Lauf beim nächsten Start nach – ein verpasstes Backup fällt so nicht einfach aus. Aktiviere den Timer:

Terminal
systemctl daemon-reload
systemctl enable --now backup-demo.timer

Alle aktiven Timer und ihre nächste Ausführung zeigt:

Terminal
systemctl list-timers
Ausgabe
NEXT                        LEFT  UNIT                ACTIVATES
Sat 2026-07-25 03:00:00 CEST 7h   backup-demo.timer   backup-demo.service

OnCalendar-Ausdrücke testen

Bevor du einen komplizierten Zeitplan aktivierst, prüfe ihn mit systemd-analyze calendar "Mon *-*-* 09:00:00" – das zeigt dir die nächsten Ausführungszeitpunkte, ohne etwas zu starten. So vermeidest du Timer, die nie oder zur falschen Zeit feuern.

Genau dieses Muster – ein oneshot-Service plus Timer – nutzen die Restic-Backups der Serverküche. Du hast damit das Werkzeug für jede wiederkehrende Wartungsaufgabe in der Hand.

Wenn es nicht funktioniert

systemctl start schlägt fehl, der Dienst ist sofort wieder dead. Lies die Details mit journalctl -u DIENST -n 30. Bei eigenen Units ist die häufigste Ursache ein falscher Pfad in ExecStart – der Befehl muss mit absolutem Pfad stehen (/usr/bin/bash, nicht bash).

„Unit changed on disk, run daemon-reload". Du hast eine Unit-Datei bearbeitet, aber systemd liest Änderungen nicht automatisch. Nach jeder Änderung an /etc/systemd/system/ gilt: systemctl daemon-reload.

Der Timer taucht in list-timers nicht auf. Er wurde nicht aktiviert. systemctl enable --now DIENST.timer – und daran denken, dass der Timer den Service auslöst, du also beide Dateien brauchst (.service und .timer).

enable meldet „static". Der Unit fehlt der Abschnitt [Install] mit WantedBy=. Ohne ihn weiß systemd nicht, wann die Unit automatisch starten soll – bei Timern gehört WantedBy=timers.target hinein.

Das Journal ist riesig / frisst Platz. Standardmäßig wächst es begrenzt, aber du kannst es beschneiden: journalctl --vacuum-time=14d löscht Einträge älter als 14 Tage, journalctl --disk-usage zeigt den Verbrauch.

Wartung & Backups

  • Eigene Units gehören ins Backup. Alles unter /etc/systemd/system/ ist deine eigene Konfiguration und sollte im Restic-Backup liegen. Nach einem Server-Neuaufbau stellst du damit deine Dienste und Timer sofort wieder her (danach einmal daemon-reload und die Timer neu enablen).
  • Timer statt eigener Cron-Jobs. Wenn du ohnehin systemd nutzt, sind Timer die konsistentere Wahl: Sie laufen im Journal auf, holen verpasste Läufe nach (Persistent=true) und lassen sich mit systemctl status DIENST genauso überwachen wie jeder andere Dienst.
  • Failed-Units im Blick behalten. systemctl --failed listet Dienste, die abgestürzt sind – ein schneller Gesundheitscheck fürs System. Für echte Alarmierung meldet dir Uptime Kuma den Ausfall des Servers, während systemctl --failed die Ursache auf dem Host zeigt.

Feedback per E-Mail: feedback@serverkueche.de

Das könnte dir auch schmecken

Erste Schritte mit einem netcup VPS
Grundlagen Einsteiger

Erste Schritte mit einem netcup VPS

Vom bestellten Server zum einsatzbereiten System: SSH-Login, Updates, ein sudo-Benutzer und die wichtigsten Handgriffe …

· 5 Min. Lesezeit