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-ServicesUnit-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.targetService aktivieren
# Systemd neu laden
systemctl daemon-reload
# Service aktivieren (Autostart)
systemctl enable myapp
# Service starten
systemctl start myapp
# Status prüfen
systemctl status myappService-Typen
Type=simple (Standard)
[Service]
Type=simple
ExecStart=/usr/bin/myapp
# Prozess bleibt im VordergrundType=forking
[Service]
Type=forking
PIDFile=/var/run/myapp.pid
ExecStart=/usr/bin/myapp --daemon
# Prozess forkt sich selbstType=oneshot
[Service]
Type=oneshot
ExecStart=/usr/local/bin/cleanup.sh
RemainAfterExit=yes
# Für einmalige TasksType=notify
[Service]
Type=notify
ExecStart=/usr/bin/myapp
# Prozess sendet sd_notify() wenn bereitKonfigurationsoptionen
[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.serviceRestart-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 MinutenUmgebungsvariablen
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=localhostPraktische 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.targetPython-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.targetGunicorn/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.targetJava-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.targetSicherheitsoptionen
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_SERVICETimer (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.targetZugehöriger Service
# /etc/systemd/system/backup.service
[Unit]
Description=Backup Service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.shTimer aktivieren
systemctl enable --now backup.timer
systemctl list-timersTimer-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/15Verwaltungsbefehle
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 myappLogs 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 100Debugging
# Service-Konfiguration prüfen
systemctl cat myapp
# Unit-Datei validieren
systemd-analyze verify myapp.service
# Boot-Analyse
systemd-analyze blameZusammenfassung
| 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.