Coldwast
systemd Service-Datei Generator
Geben Sie den Befehl ein, der Ihre Anwendung startet, und erhalten Sie eine .service-Unit für /etc/systemd/system/, samt passenden Installationsbefehlen. Der Generator prüft außerdem Ihre Eingaben und weist auf die Fehler hin, an denen eine Unit schon beim ersten Start scheitert. Alles läuft in Ihrem Browser.

Ihre Unit-Datei
Was dem Generator aufgefallen ist
Installieren
Die fünf Zeilen, die entscheiden, ob es funktioniert
ExecStart ist keine Shell. systemd zerlegt die Zeile selbst in Argumente und startet das Programm direkt. Eine Pipe, eine Umleitung > oder && landet als wörtliches Argument bei Ihrem Programm. systemd expandiert $VAR außerdem selbst, ein wörtliches Dollarzeichen schreibt man daher $$. Erkennt der Generator Shell-Syntax, verpackt er den Befehl in /bin/sh -c und übernimmt dieses Escaping.
Verwenden Sie einen absoluten Pfad. Ein Pfad wie ./server wird sofort abgelehnt. Ein bloßer Name wie node wird akzeptiert, aber systemd sucht nur in seinen eigenen festen Verzeichnissen, nicht im PATH Ihrer Login-Shell. Ein mit nvm installiertes Node oder ein Tool in ~/.local/bin wird daher nicht gefunden.
Type=simple oder exec für fast alles. Ein Webserver, ein Worker oder ein Bot, der im Vordergrund bleibt, ist simple. exec unterscheidet sich in einem nützlichen Punkt: der Start gilt erst als erfolgreich, wenn das Binary tatsächlich ausgeführt wurde. Ein falscher Pfad lässt also systemctl start scheitern, statt einen Moment später still zu scheitern. forking ist für alte Daemons, die sich selbst in den Hintergrund schicken, und notify funktioniert nur, wenn das Programm sd_notify aufruft.
Restart=on-failure, mit Grenze. on-failure startet nach einem Absturz oder einem Exit-Code ungleich null neu, nicht aber nach einem sauberen Stopp; always startet selbst dann neu. Standardmäßig erlaubt systemd 5 Starts in 10 Sekunden, und bei 5 Sekunden Wartezeit erreicht eine abstürzende App diese Grenze nie: sie läuft endlos im Kreis. StartLimitIntervalSec=300 mit StartLimitBurst=5 lässt systemd aufgeben und einen klaren Fehlerzustand hinterlassen.
Wants= und After= zusammen. After=network-online.target allein legt nur eine Reihenfolge fest; es zieht das Target nicht herein. Ohne Wants=network-online.target kann Ihr Dienst trotzdem starten, bevor das Netzwerk bereit ist. Das ist der klassische Fehler „läuft nach manuellem Neustart, scheitert beim Booten“.
Die Isolation, und was bewusst fehlt
Mit ProtectSystem=strict ist das gesamte Dateisystem für den Dienst schreibgeschützt, außer den Pfaden in ReadWritePaths=. PrivateTmp gibt ihm ein eigenes /tmp, NoNewPrivileges verhindert, dass er über setuid-Binaries Rechte gewinnt, und die Kernel- und cgroup-Einstellungen verhindern, dass er den Systemzustand ändert. Führen Sie systemd-analyze security ihreapp.service vorher und nachher aus: es zeigt einen Exposure-Score und listet jede noch offene Einstellung.
Zwei verbreitete Empfehlungen fehlen absichtlich. MemoryDenyWriteExecute=true bricht Just-in-time-Compiler, also Node.js, die JVM und PyPy. PrivateDevices=true ist für eine Web-App unproblematisch, bricht aber alles, was mit einer GPU oder einer seriellen Schnittstelle spricht. Ergänzen Sie sie selbst, wenn Sie wissen, dass Ihr Programm sie nicht braucht.

Wenn er nicht startet: die Exit-Codes
systemctl status ihreapp zeigt einen Status wie status=203/EXEC. Die Zahl verrät, welcher Schritt scheiterte, bevor Ihr Programm überhaupt lief:
| Status | Bedeutung | Übliche Lösung |
|---|---|---|
203/EXEC | Das Programm konnte nicht ausgeführt werden | Falscher Pfad, fehlendes Ausführungsrecht oder Skript ohne Shebang-Zeile |
200/CHDIR | WorkingDirectory fehlt oder ist nicht erreichbar | Anlegen oder prüfen, ob ProtectHome es ausblendet |
217/USER | Das Konto aus User= existiert nicht | Die useradd-Zeile oben ausführen |
226/NAMESPACE | Die Isolation konnte nicht eingerichtet werden | Ein Pfad in ReadWritePaths existiert nicht: anlegen oder mit - voranstellen |
Jeder andere Fehler ist Ihr eigenes Programm, das sich beendet, und seine Ausgabe steht in journalctl -u ihreapp -b.
Später ändern
Nach dem Bearbeiten der Datei in /etc/systemd/system/ führen Sie sudo systemctl daemon-reload vor dem Neustart aus, sonst verwendet systemd weiter die alte Fassung. Eine von einem Paket installierte Unit bearbeiten Sie nicht direkt: sudo systemctl edit ihreapp legt eine Override-Datei an, die Updates übersteht, und lädt systemd für Sie neu.
Weiterlesen: was ein VPS ist, einen Reverse Proxy vor die App setzen, SSH-Grundlagen und für geplante Aufgaben der Cron-Ausdruck-Erklärer.