Il guasto è tipico: il servizio parte, ma trova /run/app assente o con permessi sbagliati. Dopo un reboot la directory non torna, il socket fallisce, e il ripristino manuale dura pochi minuti. Il punto debole è spesso systemd-tmpfiles, non l’applicazione.
Questo caso vale più di un tutorial base perché il problema emerge solo dopo il riavvio. In produzione è fastidioso: il servizio funziona a caldo, poi si rompe al boot successivo. Qui vediamo come leggere i segnali, correggere la regola, fare rollback e verificare il ripristino.
Prerequisiti
- Accesso root o sudo.
- Una distro con systemd e tmpfiles attivi.
- Nome del servizio o dell’app che usa /run/app o un path simile.
- Accesso ai log di journalctl.
Note: /run è tmpfs. Il contenuto sparisce al reboot. Se ci metti dati persistenti, il problema torna sempre.
Step numerati
1) Capire il sintomo reale prima di toccare la config
Perché: se la directory è creata da uno script manuale, il reboot la cancella. Devi capire se il guasto è nel boot o nel servizio.
systemctl status app.service --no-pager
journalctl -b -u app.service --no-pager
ls -ld /run/app
# Output:
# /run/app: No such file or directory
# app.service: failed to start because /run/app is missingSe il path manca solo dopo il reboot, il sospetto principale è una regola tmpfiles assente, sbagliata o caricata troppo tardi.
Warning: non creare la directory con mkdir -p e basta. È una toppa che non sopravvive al boot.
2) Verificare la regola tmpfiles attesa
Perché: tmpfiles non inventa nulla. Serve una riga esplicita in /etc/tmpfiles.d/ oppure in /usr/lib/tmpfiles.d/.
grep -R "^d /run/app" /etc/tmpfiles.d /usr/lib/tmpfiles.d 2>/dev/null
systemd-tmpfiles --cat-config | grep -n " /run/app"
# Output:
# d /run/app 0750 app app - -Se la riga non esiste, il boot non creerà nulla. Se esiste ma il proprietario è sbagliato, il servizio può partire ma fallire sul socket o sui file runtime.
Un formato corretto è questo:
d /run/app 0750 app app - -Il primo campo d crea la directory. I permessi devono essere coerenti con l’utente del servizio.
3) Scrivere una regola corretta e minimale
Perché: la regola deve essere chiara, stabile e facile da rollbackare.
cat > /etc/tmpfiles.d/app.conf <<'EOF'
d /run/app 0750 app app - -
EOF
systemd-tmpfiles --create /etc/tmpfiles.d/app.conf
# Output:
# Created directory /run/app.Se il servizio usa un socket o una cache runtime, crea solo ciò che serve. Più roba metti in /run, più aumentano gli effetti collaterali al reboot.
Note: il file in /etc/tmpfiles.d/ ha priorità operativa per l’amministrazione locale. È il posto giusto per una correzione del sito o del servizio.
4) Se il servizio parte troppo presto, correggere l’ordine di boot
Perché: a volte tmpfiles è giusto, ma il servizio parte prima della creazione della directory. Succede con unità personalizzate o dipendenze incomplete.
systemctl edit app.service
# inserire:
# [Unit]
# After=systemd-tmpfiles-setup.service
# Requires=systemd-tmpfiles-setup.service
# Output:
# Drop-in creato in /etc/systemd/system/app.service.d/override.confSe il servizio ha bisogno della directory solo al boot, questa dipendenza evita il race. Non abusarne, però. Se il problema è un path persistente mal progettato, meglio spostarlo fuori da /run.
5) Ripristinare in modo sicuro senza perdere dati
Perché: quando il path runtime è rotto, spesso c’è confusione tra cache temporanea e dati importanti. Prima isola, poi ripulisci.
systemctl stop app.service
mv /run/app /run/app.bak.$(date +%F-%H%M%S) 2>/dev/null || true
systemd-tmpfiles --create /etc/tmpfiles.d/app.conf
systemctl start app.service
# Output:
# app.service: active (running)Se il servizio riparte, la regola è coerente. Se fallisce ancora, il problema è probabilmente nel profilo utente, nel socket o in un permesso ereditato da un’unità precedente.
Warning: non usare rm -rf /run/app alla cieca se il servizio scrive file temporanei utili per il debug. Prima fai un backup della directory, anche se è runtime.
6) Salvare il fix in modo che sopravviva a reboot e update
Perché: la riparazione manuale deve diventare configurazione gestita. Altrimenti torna il problema al prossimo aggiornamento del pacchetto.
systemctl daemon-reload
systemctl enable app.service
systemd-tmpfiles --create --boot
# Output:
# Created /run/app on bootSe il pacchetto installa una sua regola in /usr/lib/tmpfiles.d/, evita di modificarla direttamente. Meglio aggiungere un override in /etc/tmpfiles.d/, così il rollback è semplice.
Verifica finale
Riavvia il server in finestra di manutenzione. Poi controlla tre cose: la directory esiste, proprietario e permessi sono corretti, il servizio è attivo.
reboot
# dopo il ritorno
ls -ld /run/app
systemctl is-active app.service
journalctl -b -u app.service --no-pager | tail -n 20
# Output:
# drwxr-x--- 2 app app ... /run/app
# active
# started successfullySe vuoi una verifica più dura, simula l’avvio a freddo con un test controllato in staging. È il modo migliore per scoprire race condition che a caldo non si vedono.
Troubleshooting
Errore: systemd-tmpfiles[...]: Failed to create directory /run/app: No such file or directory
Causa: la riga punta a un path padre inesistente o usa una sintassi errata.
systemd-tmpfiles --create --prefix=/run/app -v
systemd-analyze verify app.service
# Output:
# parent path missing or invalid tmpfiles entryFix: correggi il path e verifica che il file non abbia spazi o campi mancanti.
Errore: app.service: Failed at step CHDIR spawning ...: No such file or directory
Causa: il servizio usa WorkingDirectory=/run/app ma tmpfiles non ha creato la directory prima del start.
systemctl cat app.service
systemctl edit app.service
# aggiungi After=systemd-tmpfiles-setup.service
# Output:
# unit updatedFix: aggiungi la dipendenza o sposta il working directory su un path persistente.
Errore: Permission denied su socket o file in /run/app
Causa: owner o mode non corrispondono all’utente effettivo del servizio.
id app
stat /run/app
sed -i 's#^d /run/app .*#d /run/app 0750 app app - -#' /etc/tmpfiles.d/app.conf
systemd-tmpfiles --create /etc/tmpfiles.d/app.conf
# Output:
# permissions correctedFix: riallinea owner e permessi con l’utente del processo, poi riavvia il servizio.
Conclusione
Un path runtime che sparisce al reboot non è un dettaglio minore. Di solito segnala una regola tmpfiles assente o un ordine di avvio sbagliato.
La correzione giusta è piccola, ma va verificata a freddo. Il prossimo passo concreto è mettere il controllo in staging e aggiungere un alert sul fallimento di app.service al boot.
Commenti (0)
Nessun commento ancora.
Segnala contenuto
Elimina commento
Eliminare definitivamente questo commento?
L'azione non si può annullare.