Introduzione
Quando un servizio non parte al boot, il problema quasi mai è “misterioso”: in genere c’è un errore nel file di unità, una dipendenza mancante, un permesso sbagliato, una porta già occupata oppure una configurazione valida a mano ma non valida all’avvio automatico. La strada più veloce non è riavviare a vuoto, ma leggere lo stato del servizio, isolare il punto di rottura e correggere solo quello.
Questa guida vale per la maggior parte delle distribuzioni con systemd, quindi Ubuntu, Debian, AlmaLinux, Rocky Linux e CentOS moderni. L’obiettivo è arrivare a una diagnosi pulita, poi applicare un fix minimo e verificare che il servizio parta davvero al boot.
1) Prima domanda: il servizio fallisce sempre o solo al boot?
Se il servizio parte manualmente ma non all’avvio, il guasto è spesso legato a dipendenze non ancora pronte, a directory montate in ritardo, a variabili d’ambiente mancanti o a credenziali non disponibili nel contesto di systemd. Se invece fallisce anche a mano, il problema è più vicino alla configurazione applicativa o alla binaria stessa.
Questa distinzione cambia il metodo di intervento. Nel primo caso si lavora sulla unit o sul timing. Nel secondo caso si parte dai log dell’applicazione e dalla validazione della configurazione.
2) Verifiche immediate
- Controlla lo stato del servizio con un comando che mostri motivo del fallimento ed eventuale codice di errore:
systemctl status nome-servizio --no-pager -lEsito atteso: vedi Active: failed, un messaggio chiaro e spesso una riga con il codice di uscita o la causa immediata.
- Leggi i log del boot corrente per lo stesso servizio:
journalctl -u nome-servizio -b --no-pager -n 100Esito atteso: compare l’errore reale, non solo il sintomo. Cerca stringhe come failed to bind, permission denied, configuration file error, dependency failed, timeout.
- Verifica se la porta è già occupata se il servizio ascolta su rete:
ss -ltnp | grep -E ':(80|443|3306|5432|8080)'Esito atteso: nessun processo in conflitto sulla porta del servizio. Se trovi un altro processo, hai già una causa concreta.
- Controlla la validità della configurazione prima di riavviare, se l’app la supporta. Esempi comuni:
nginx -t
apachectl configtest
php-fpm -tEsito atteso: syntax is ok o equivalente. Se fallisce, non riavviare: correggi prima la configurazione.
3) Diagnosi probabile
Le cause più frequenti sono queste:
- Errore nella configurazione del servizio: un file di config contiene sintassi errata, path sbagliati o direttive non supportate dalla versione installata.
- Dipendenza non pronta al boot: il servizio parte prima del database, di un mount remoto, di una rete VLAN o di un volume NFS.
- Permessi o ownership errati: l’utente di servizio non può leggere file, certificati, socket o directory di runtime.
- Porta o socket già occupati: un altro processo usa la stessa porta o il socket è rimasto in stato incoerente.
- Ambiente diverso tra shell e systemd: variabili presenti nella sessione interattiva ma assenti nell’unit, percorsi non esportati, limiti di risorse diversi.
- Risorse insufficienti: memoria bassa, OOM killer, disco pieno, inode esauriti o timeout troppo stretto.
4) Soluzione consigliata passo-passo
- Recupera il nome esatto dell’unit e il suo contenuto, così eviti di intervenire sul servizio sbagliato:
systemctl list-units --type=service --all | grep -i nomeSe la unit è custom, controlla anche il file in
/etc/systemd/system/o/lib/systemd/system/. Se il servizio è gestito da un pannello come cPanel o Plesk, verifica che non sia stato creato un override automatico. - Analizza il file di unit e gli eventuali override prima di cambiare qualcosa. Fai un backup del file se prevedi modifiche:
cp /etc/systemd/system/nome-servizio.service /etc/systemd/system/nome-servizio.service.bakControlla se esistono drop-in in
/etc/systemd/system/nome-servizio.service.d/. Un override dimenticato può bloccare il boot anche se il file principale è corretto. - Se il problema è una dipendenza, aggiungi un avvio più prudente invece di forzare riavvii ciechi. In molti casi aiutano direttive come
After=,Requires=o un ritardo controllato viaExecStartPre. Esempio concettuale: il servizio database deve essere operativo prima del web app. Dopo la modifica, ricarica systemd:systemctl daemon-reloadEsito atteso: systemd rilegge la configurazione senza errori.
- Se il problema è un permesso, correggi ownership e modalità sul file o sulla directory indicata dai log. Esempio tipico per un servizio web o app:
chown -R utente:gruppo /percorso/datiEsito atteso: il servizio riesce a leggere e scrivere solo dove serve. Evita permessi troppo larghi: il fix deve essere minimo e reversibile.
- Se il problema è una porta già occupata, identifica il processo in conflitto e decidi quale dei due deve restare attivo:
lsof -i :8080Esito atteso: trovi il PID responsabile. Se il processo è legittimo, cambia la porta del servizio; se è un duplicato, ferma solo l’istanza superflua.
- Se il problema è il timeout di avvio, aumenta il tempo disponibile solo dopo aver confermato che il servizio è lento ma corretto. Puoi farlo nell’unit con
TimeoutStartSec=. Dopo la modifica, ricarica e prova l’avvio manuale:systemctl daemon-reload
systemctl restart nome-servizioEsito atteso: il servizio passa a active (running) senza andare in timeout.
- Se il servizio dipende da rete o mount, verifica che il punto di montaggio sia presente e che la rete sia realmente pronta prima dell’avvio. Per un mount remoto, controlla
/etc/fstabe lo stato del mount con:mount | grep /percorso
systemctl status remote-fs.targetEsito atteso: il volume risulta montato prima che il servizio ne faccia uso.
- Testa l’avvio in modo controllato, senza aspettare il prossimo reboot:
systemctl restart nome-servizio
systemctl status nome-servizio --no-pager -lEsito atteso: il servizio resta attivo e non genera nuovi errori nel journal.
5) Caso speciale: il servizio parte a mano ma non al reboot
Questo è il caso più comune nei server reali. Qui il problema non è l’app, ma il contesto di avvio. Le correzioni più utili sono:
- Verificare l’ordine di avvio: il servizio può partire troppo presto rispetto al database, a una VPN, a un mount NFS o a un reverse proxy.
- Controllare le variabili d’ambiente: systemd non eredita automaticamente la shell dell’utente. Se la tua app legge
.envo file esterni, assicurati che il percorso sia esplicito. - Controllare l’utente di esecuzione: un servizio che da root funziona e da utente dedicato no ha quasi sempre un problema di permessi o path.
- Controllare i limiti di systemd: memoria, file descriptor e directory temporanee possono essere più restrittivi rispetto alla shell manuale.
In questi casi, leggere il file unit e il journal del boot è più utile di qualsiasi riavvio ripetuto.
6) Esempio pratico: un servizio web non sale al boot
Supponiamo che un server web non parta dopo il riavvio. I sintomi mostrano failed to bind sulla porta 443. Le verifiche immediate indicano che un secondo processo già ascolta su quella porta, magari un vecchio container o un altro web server.
La soluzione corretta non è “forzare” il servizio a partire, ma decidere quale processo deve occupare la porta. Se il servizio giusto è quello nuovo, ferma il processo vecchio e abilita l’avvio automatico del servizio corretto. Se invece il processo vecchio è quello giusto, disabilita il nuovo servizio o cambia la sua porta.
Dopo la correzione, esegui sempre almeno questi due controlli:
systemctl is-enabled nome-servizio
systemctl is-active nome-servizioEsito atteso: il servizio risulta enabled e active se deve partire al boot.
7) Se il log non basta: controlli di supporto
Quando i messaggi del journal non sono sufficienti, allarga il campo con controlli di base:
- Spazio disco e inode: un filesystem pieno può impedire la creazione di PID, socket e log.
- Memoria e OOM: se il kernel ha terminato il processo, cerca eventi OOM nel journal di sistema.
- Stato SELinux o AppArmor: su sistemi con MAC attivo, un blocco di policy può sembrare un errore di permesso.
- Connettività esterna: se il servizio deve contattare un database remoto o un’API, il boot può fallire per un timeout di rete.
Controlli utili:
df -h
df -i
journalctl -k -b --no-pager | grep -i -E 'oom|killed process|selinux|apparmor'Esito atteso: nessun esaurimento di spazio o segnale di blocco dal kernel.
8) Quando toccare il file di unit e quando no
Modifica il file di unit solo se hai trovato una causa chiara. Se non hai ancora una prova, rischi di mascherare il problema senza risolverlo. La regola pratica è semplice: prima prova, poi modifica.
Intervieni sull’unit se il difetto riguarda ordine di avvio, ambiente, timeout o dipendenze. Non intervenire sull’unit se il problema è dentro l’applicazione, nella sintassi della config o nel codice che la usa.
9) Controlli finali / rollback
- Verifica finale: dopo il fix, controlla che il servizio sia attivo e che non compaiano nuovi errori nel journal:
systemctl status nome-servizio --no-pager -l
journalctl -u nome-servizio -b --no-pager -n 50Successo atteso: nessun errore ricorrente e stato active (running).
- Persistenza al reboot: abilita il servizio solo se deve davvero partire automaticamente:
systemctl enable nome-servizioEsito atteso: il servizio è marcato per l’avvio automatico al boot.
- Rollback: se il cambio su unit o configurazione peggiora la situazione, ripristina il backup del file modificato e ricarica systemd:
cp /etc/systemd/system/nome-servizio.service.bak /etc/systemd/system/nome-servizio.service
systemctl daemon-reload
systemctl restart nome-servizioCondizione di rollback: il servizio torna a uno stato noto e i log riprendono a mostrare l’errore originale, non un errore nuovo introdotto dal fix.
Assunzione operativa: il sistema usa systemd e hai accesso con privilegi amministrativi per leggere i log e ricaricare le unità.
10) Checklist rapida
- Ho letto
systemctl statuse il journal del boot. - Ho verificato porte, permessi e dipendenze prima di cambiare qualcosa.
- Ho fatto un backup del file di unit se dovevo modificarlo.
- Ho testato il servizio con un restart manuale.
- Ho verificato che l’avvio automatico funzioni davvero dopo il reboot.
Con questo approccio, il guasto smette di essere “il servizio non parte” e diventa un problema concreto con una causa leggibile, correggibile e verificabile.
Commenti (0)
Nessun commento ancora.
Segnala contenuto
Elimina commento
Eliminare definitivamente questo commento?
L'azione non si può annullare.