54 02/04/2026 07/04/2026 8 min

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

  1. Controlla lo stato del servizio con un comando che mostri motivo del fallimento ed eventuale codice di errore:
    systemctl status nome-servizio --no-pager -l

    Esito atteso: vedi Active: failed, un messaggio chiaro e spesso una riga con il codice di uscita o la causa immediata.

  2. Leggi i log del boot corrente per lo stesso servizio:
    journalctl -u nome-servizio -b --no-pager -n 100

    Esito atteso: compare l’errore reale, non solo il sintomo. Cerca stringhe come failed to bind, permission denied, configuration file error, dependency failed, timeout.

  3. 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.

  4. Controlla la validità della configurazione prima di riavviare, se l’app la supporta. Esempi comuni:
    nginx -t
    apachectl configtest
    php-fpm -t

    Esito atteso: syntax is ok o equivalente. Se fallisce, non riavviare: correggi prima la configurazione.

3) Diagnosi probabile

Le cause più frequenti sono queste:

  1. Errore nella configurazione del servizio: un file di config contiene sintassi errata, path sbagliati o direttive non supportate dalla versione installata.
  2. Dipendenza non pronta al boot: il servizio parte prima del database, di un mount remoto, di una rete VLAN o di un volume NFS.
  3. Permessi o ownership errati: l’utente di servizio non può leggere file, certificati, socket o directory di runtime.
  4. Porta o socket già occupati: un altro processo usa la stessa porta o il socket è rimasto in stato incoerente.
  5. Ambiente diverso tra shell e systemd: variabili presenti nella sessione interattiva ma assenti nell’unit, percorsi non esportati, limiti di risorse diversi.
  6. Risorse insufficienti: memoria bassa, OOM killer, disco pieno, inode esauriti o timeout troppo stretto.

4) Soluzione consigliata passo-passo

  1. 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 nome

    Se 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.

  2. 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.bak

    Controlla 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.

  3. 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 via ExecStartPre. Esempio concettuale: il servizio database deve essere operativo prima del web app. Dopo la modifica, ricarica systemd:
    systemctl daemon-reload

    Esito atteso: systemd rilegge la configurazione senza errori.

  4. 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/dati

    Esito atteso: il servizio riesce a leggere e scrivere solo dove serve. Evita permessi troppo larghi: il fix deve essere minimo e reversibile.

  5. Se il problema è una porta già occupata, identifica il processo in conflitto e decidi quale dei due deve restare attivo:
    lsof -i :8080

    Esito atteso: trovi il PID responsabile. Se il processo è legittimo, cambia la porta del servizio; se è un duplicato, ferma solo l’istanza superflua.

  6. 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-servizio

    Esito atteso: il servizio passa a active (running) senza andare in timeout.

  7. 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/fstab e lo stato del mount con:
    mount | grep /percorso
    systemctl status remote-fs.target

    Esito atteso: il volume risulta montato prima che il servizio ne faccia uso.

  8. Testa l’avvio in modo controllato, senza aspettare il prossimo reboot:
    systemctl restart nome-servizio
    systemctl status nome-servizio --no-pager -l

    Esito 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:

  1. 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.
  2. Controllare le variabili d’ambiente: systemd non eredita automaticamente la shell dell’utente. Se la tua app legge .env o file esterni, assicurati che il percorso sia esplicito.
  3. 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.
  4. 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-servizio

Esito 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:

  1. Spazio disco e inode: un filesystem pieno può impedire la creazione di PID, socket e log.
  2. Memoria e OOM: se il kernel ha terminato il processo, cerca eventi OOM nel journal di sistema.
  3. Stato SELinux o AppArmor: su sistemi con MAC attivo, un blocco di policy può sembrare un errore di permesso.
  4. 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

  1. 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 50

    Successo atteso: nessun errore ricorrente e stato active (running).

  2. Persistenza al reboot: abilita il servizio solo se deve davvero partire automaticamente:
    systemctl enable nome-servizio

    Esito atteso: il servizio è marcato per l’avvio automatico al boot.

  3. 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-servizio

    Condizione 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 status e 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.