Coldwast
Generatore di file di servizio systemd
Inserisci il comando che avvia la tua applicazione e ottieni un'unità .service da mettere in /etc/systemd/system/, con i relativi comandi di installazione. Il generatore rilegge anche ciò che hai scritto e segnala gli errori che fanno fallire un'unità al primo avvio. Tutto gira nel tuo browser.

Il tuo file di unità
Cosa ha notato il generatore
Installarlo
Le cinque righe che decidono se funziona
ExecStart non è una shell. systemd divide da solo la riga in argomenti ed esegue direttamente il programma. Una pipe, una redirezione > o un && arriva al tuo programma come argomento letterale. systemd espande anche $VAR per conto suo, quindi un dollaro letterale si scrive $$. Quando il generatore rileva sintassi di shell, avvolge il comando in /bin/sh -c e fa questo escape al posto tuo.
Usa un percorso assoluto. Un percorso come ./server viene rifiutato subito. Un nome senza percorso come node è accettato, ma systemd cerca solo nelle proprie directory fisse, non nel PATH della tua shell: un Node installato con nvm o uno strumento in ~/.local/bin non viene trovato.
Type=simple o exec per quasi tutto. Un server web, un worker o un bot che resta in primo piano è simple. exec differisce in un punto utile: l'avvio viene considerato riuscito solo quando il binario è stato davvero eseguito, quindi un percorso sbagliato fa fallire systemctl start invece di fallire in silenzio un attimo dopo. forking serve ai vecchi demoni che vanno da soli in background, e notify funziona solo se il programma chiama sd_notify.
Restart=on-failure, con un limite. on-failure riavvia dopo un crash o un'uscita diversa da zero, ma non dopo un arresto pulito; always riavvia anche in quel caso. Per impostazione predefinita systemd consente 5 avvii in 10 secondi, e con un'attesa di 5 secondi un'app che va in crash non raggiunge mai quel limite: gira in tondo all'infinito. StartLimitIntervalSec=300 con StartLimitBurst=5 la fa arrendere e lascia uno stato di errore chiaro.
Wants= e After= insieme. After=network-online.target da solo fissa soltanto un ordine; non attiva il target. Senza Wants=network-online.target il servizio può comunque partire prima che la rete sia pronta: il classico «funziona dopo un riavvio manuale, fallisce al boot».
L'isolamento, e ciò che è stato escluso di proposito
Con ProtectSystem=strict l'intero filesystem è in sola lettura per il servizio, tranne i percorsi elencati in ReadWritePaths=. PrivateTmp gli dà un proprio /tmp, NoNewPrivileges gli impedisce di ottenere privilegi tramite binari setuid, e le impostazioni del kernel e dei cgroup gli impediscono di modificare lo stato del sistema. Esegui systemd-analyze security tuaapp.service prima e dopo: mostra un punteggio di esposizione ed elenca ogni impostazione ancora aperta.
Due raccomandazioni comuni mancano di proposito. MemoryDenyWriteExecute=true rompe i compilatori just-in-time, cioè Node.js, la JVM e PyPy. PrivateDevices=true va bene per un'app web ma rompe tutto ciò che comunica con una GPU o una porta seriale. Aggiungile tu se sai che il tuo programma non ne ha bisogno.

Quando non parte: i codici di uscita
systemctl status tuaapp mostra uno stato come status=203/EXEC. Il numero indica quale passaggio è fallito prima ancora che il programma partisse:
| Stato | Significato | Soluzione abituale |
|---|---|---|
203/EXEC | Impossibile eseguire il programma | Percorso errato, permesso di esecuzione mancante o script senza riga shebang |
200/CHDIR | WorkingDirectory mancante o non accessibile | Crearla, o verificare che ProtectHome non la nasconda |
217/USER | L'account di User= non esiste | Eseguire la riga useradd qui sopra |
226/NAMESPACE | Impossibile predisporre l'isolamento | Un percorso in ReadWritePaths non esiste: crearlo o anteporgli - |
Qualsiasi altro errore è il tuo programma che termina, e il suo output è in journalctl -u tuaapp -b.
Modificarlo in seguito
Dopo aver modificato il file in /etc/systemd/system/, esegui sudo systemctl daemon-reload prima di riavviare, altrimenti systemd continua a usare la vecchia versione. Per un'unità installata da un pacchetto, non modificarla sul posto: sudo systemctl edit tuaapp crea un file di override che sopravvive agli aggiornamenti e ricarica systemd per te.
Da leggere anche: che cos'è un VPS, mettere un reverse proxy davanti all'app, le basi di SSH e, per i processi pianificati, il decodificatore di espressioni cron.