Systemd ist das Standard-Init-System moderner Linux-Distributionen. Es startet Dienste, verwaltet Abhängigkeiten und überwacht Prozesse. Hier lernen Sie, eigene Services zu erstellen.

Systemd-Grundlagen

Wichtige Verzeichnisse

/etc/systemd/system/        # Eigene Services (höchste Priorität)
/run/systemd/system/        # Runtime-Services
/lib/systemd/system/        # Distributions-Services

Unit-Typen

| Typ | Endung | Verwendung | |-----|--------|------------| | Service | .service | Daemon/Dienst | | Socket | .socket | Socket-Aktivierung | | Timer | .timer | Geplante Aufgaben | | Mount | .mount | Dateisysteme | | Target | .target | Gruppierung |

Service erstellen

Einfacher Service

# /etc/systemd/system/myapp.service

[Unit]
Description=My Application
After=network.target

[Service]
Type=simple
User=myuser
Group=mygroup
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/start.sh
Restart=on-failure

[Install]
WantedBy=multi-user.target

Service aktivieren

# Systemd neu laden
systemctl daemon-reload

# Service aktivieren (Autostart)
systemctl enable myapp

# Service starten
systemctl start myapp

# Status prüfen
systemctl status myapp

Service-Typen

Type=simple (Standard)

[Service]
Type=simple
ExecStart=/usr/bin/myapp
# Prozess bleibt im Vordergrund

Type=forking

[Service]
Type=forking
PIDFile=/var/run/myapp.pid
ExecStart=/usr/bin/myapp --daemon
# Prozess forkt sich selbst

Type=oneshot

[Service]
Type=oneshot
ExecStart=/usr/local/bin/cleanup.sh
RemainAfterExit=yes
# Für einmalige Tasks

Type=notify

[Service]
Type=notify
ExecStart=/usr/bin/myapp
# Prozess sendet sd_notify() wenn bereit

Konfigurationsoptionen

[Unit] Section

[Unit]
# Beschreibung
Description=My Application Service

# Dokumentation
Documentation=https://example.com/docs

# Abhängigkeiten
After=network.target mysql.service
Requires=mysql.service
Wants=redis.service

# Konflikte
Conflicts=other.service

[Service] Section

[Service]
# Prozess-Typ
Type=simple

# Benutzer/Gruppe
User=www-data
Group=www-data

# Arbeitsverzeichnis
WorkingDirectory=/opt/myapp

# Befehle
ExecStartPre=/opt/myapp/pre-start.sh
ExecStart=/opt/myapp/start.sh
ExecStartPost=/opt/myapp/post-start.sh
ExecStop=/opt/myapp/stop.sh
ExecReload=/bin/kill -HUP $MAINPID

# Umgebungsvariablen
Environment="NODE_ENV=production"
Environment="PORT=3000"
EnvironmentFile=/etc/myapp/env

# Neustart-Verhalten
Restart=always
RestartSec=5
StartLimitInterval=60
StartLimitBurst=3

# Timeouts
TimeoutStartSec=30
TimeoutStopSec=30

# Ressourcenlimits
LimitNOFILE=65535
LimitNPROC=4096

[Install] Section

[Install]
# Wann starten
WantedBy=multi-user.target

# Aliase
Alias=myapp.service

Restart-Optionen

Restart-Verhalten

| Wert | Beschreibung | |------|--------------| | no | Nie neu starten | | always | Immer neu starten | | on-failure | Bei Fehler (Exit != 0) | | on-abnormal | Bei Signal/Timeout | | on-abort | Bei Signal | | on-success | Bei Exit = 0 |

Beispiel mit Limits

[Service]
Restart=on-failure
RestartSec=10
StartLimitInterval=300
StartLimitBurst=5
# Max 5 Neustarts in 5 Minuten

Umgebungsvariablen

Direkt in Service

[Service]
Environment="NODE_ENV=production"
Environment="PORT=3000"
Environment="DB_HOST=localhost"

Aus Datei

[Service]
EnvironmentFile=/etc/myapp/myapp.env
# /etc/myapp/myapp.env
NODE_ENV=production
PORT=3000
DB_HOST=localhost

Praktische Beispiele

Node.js Application

# /etc/systemd/system/nodeapp.service

[Unit]
Description=Node.js Application
After=network.target

[Service]
Type=simple
User=nodeapp
WorkingDirectory=/opt/nodeapp
ExecStart=/usr/bin/node /opt/nodeapp/server.js
Restart=on-failure
RestartSec=10

Environment=NODE_ENV=production
Environment=PORT=3000

# Graceful shutdown
KillMode=mixed
TimeoutStopSec=30

[Install]
WantedBy=multi-user.target

Python-Anwendung

# /etc/systemd/system/pythonapp.service

[Unit]
Description=Python Application
After=network.target

[Service]
Type=simple
User=pythonapp
Group=pythonapp
WorkingDirectory=/opt/pythonapp
ExecStart=/opt/pythonapp/venv/bin/python app.py
Restart=always
RestartSec=5

Environment="PYTHONUNBUFFERED=1"

[Install]
WantedBy=multi-user.target

Gunicorn/Django

# /etc/systemd/system/gunicorn.service

[Unit]
Description=Gunicorn Daemon
After=network.target

[Service]
Type=notify
User=www-data
Group=www-data
WorkingDirectory=/opt/django-app
ExecStart=/opt/django-app/venv/bin/gunicorn \
    --workers 4 \
    --bind unix:/run/gunicorn.sock \
    --access-logfile /var/log/gunicorn/access.log \
    --error-logfile /var/log/gunicorn/error.log \
    myproject.wsgi:application
ExecReload=/bin/kill -s HUP $MAINPID
Restart=on-failure

[Install]
WantedBy=multi-user.target

Java-Anwendung

# /etc/systemd/system/javaapp.service

[Unit]
Description=Java Application
After=network.target

[Service]
Type=simple
User=javaapp
WorkingDirectory=/opt/javaapp
ExecStart=/usr/bin/java -jar /opt/javaapp/app.jar
Restart=on-failure
RestartSec=10

Environment="JAVA_OPTS=-Xms256m -Xmx512m"

SuccessExitStatus=143
TimeoutStopSec=10

[Install]
WantedBy=multi-user.target

Sicherheitsoptionen

Hardening

[Service]
# Minimale Rechte
User=myuser
Group=mygroup
NoNewPrivileges=true

# Dateisystem einschränken
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
ReadOnlyPaths=/etc
ReadWritePaths=/var/lib/myapp /var/log/myapp

# Netzwerk einschränken
PrivateNetwork=false
RestrictAddressFamilies=AF_INET AF_INET6

# Capabilities
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE

Timer (Ersatz für Cron)

Timer-Unit

# /etc/systemd/system/backup.timer

[Unit]
Description=Daily Backup Timer

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

[Install]
WantedBy=timers.target

Zugehöriger Service

# /etc/systemd/system/backup.service

[Unit]
Description=Backup Service

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

Timer aktivieren

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

Timer-Syntax

# Täglich um 2:00
OnCalendar=*-*-* 02:00:00

# Stündlich
OnCalendar=hourly
OnCalendar=*-*-* *:00:00

# Montags um 9:00
OnCalendar=Mon *-*-* 09:00:00

# Alle 15 Minuten
OnCalendar=*:0/15

Verwaltungsbefehle

Service-Verwaltung

# Starten/Stoppen
systemctl start myapp
systemctl stop myapp
systemctl restart myapp
systemctl reload myapp

# Aktivieren/Deaktivieren
systemctl enable myapp
systemctl disable myapp

# Status
systemctl status myapp
systemctl is-active myapp
systemctl is-enabled myapp

Logs anzeigen

# Journal-Logs
journalctl -u myapp

# Live-Logs
journalctl -u myapp -f

# Seit Zeitpunkt
journalctl -u myapp --since "1 hour ago"

# Letzte 100 Zeilen
journalctl -u myapp -n 100

Debugging

# Service-Konfiguration prüfen
systemctl cat myapp

# Unit-Datei validieren
systemd-analyze verify myapp.service

# Boot-Analyse
systemd-analyze blame

Zusammenfassung

| Befehl | Funktion | |--------|----------| | systemctl start | Starten | | systemctl stop | Stoppen | | systemctl restart | Neu starten | | systemctl enable | Autostart aktivieren | | systemctl status | Status anzeigen | | systemctl daemon-reload | Config neu laden | | journalctl -u service | Logs anzeigen |

Fazit

Systemd-Services bieten robuste Prozessverwaltung mit automatischem Neustart, Logging und Sicherheitsfeatures. Erstellen Sie für jede Anwendung einen eigenen Service mit angemessenen Restart-Optionen und Berechtigungen. Nutzen Sie Timer statt Cronjobs für bessere Integration und verwenden Sie Journalctl für zentralisiertes Logging.