Risoluzione dei problemi di Nginx: Soluzioni comuni da riga di comando per problemi del server web

Utilizza controlli pratici da riga di comando di Nginx per lo stato del servizio, errori di configurazione, log, porte e comuni errori 4xx o 5xx.

Risoluzione dei problemi di Nginx: Soluzioni comuni da riga di comando per problemi del server web

Quando Nginx si rompe, i primi minuti sono solitamente dedicati a restringere il problema. Il servizio è fermo? Una modifica alla configurazione è fallita? Un altro processo sta già usando la porta 80? Nginx è funzionante ma l'applicazione upstream è giù? La riga di comando fornisce risposte rapide se esegui i controlli nell'ordine giusto.

Mi piace iniziare con i comandi meno distruttivi: ispezionare lo stato, testare la configurazione, leggere i log e solo dopo ricaricare o riavviare. Un riavvio può nascondere prove utili, quindi trattalo come una soluzione solo dopo aver capito cosa stai risolvendo.

Comandi essenziali di gestione di Nginx

Il primo passo nella risoluzione dei problemi è spesso verificare lo stato del servizio Nginx stesso. A seconda del sistema operativo, interagirai tipicamente con systemd o service (SysVinit).

1. Verifica dello stato del servizio Nginx

Sapere se Nginx è in esecuzione, fermo o in errore è cruciale. Il comando status fornisce questa panoramica.

Usando systemd (Comune sulle moderne distribuzioni Linux come Ubuntu 16.04+, CentOS 7+):

sudo systemctl status nginx

Output previsto (Attivo/In esecuzione):

● nginx.service - Un server web ad alte prestazioni e un server proxy inverso
   Loaded: caricato (/lib/systemd/system/nginx.service; abilitato; preset fornitore: abilitato)
   Active: attivo (in esecuzione) da mar 2023-10-24 10:00:00 UTC; 1h fa
     Docs: man:nginx(8)
 Main PID: 1234 (nginx)
    Tasks: 2 (limite: 4915)
   CGroup: /system.slice/nginx.service
           ├─1234 nginx: processo master /usr/sbin/nginx -g daemon on;
           └─1235 nginx: processo worker 

Se l'output mostra Active: inactive (dead) o Active: failed, sai che Nginx non sta attualmente servendo traffico. Questo non ti dice il perché. Il prossimo indizio è solitamente un test di configurazione o il journal di sistema.

sudo journalctl -u nginx -n 80 --no-pager

Questo mostra i log recenti del servizio, inclusi gli errori di avvio da systemd. Cerca messaggi su direttive sconosciute, file di certificato mancanti, errori di bind o problemi di permessi.

2. Avvio, arresto e ricarica di Nginx

Una volta identificato lo stato, devi gestirlo. Usa i seguenti comandi secondo necessità:

Azione Comando (usando systemctl)
Arresta Servizio sudo systemctl stop nginx
Avvia Servizio sudo systemctl start nginx
Riavvia Servizio sudo systemctl restart nginx (Ferma e poi riavvia)
Ricarica Configurazione sudo systemctl reload nginx (Applica nuove configurazioni senza interrompere le connessioni)

Buona pratica: Usa reload invece di restart Quando apporti modifiche alla configurazione (come aggiornare host virtuali o certificati SSL), usa sempre reload. Questo applica le modifiche in modo graduale mentre le connessioni esistenti continuano senza interruzioni. Usa restart solo se reload fallisce o se hai bisogno di resettare completamente i processi worker.

Prima di qualsiasi ricarica, esegui:

sudo nginx -t && sudo systemctl reload nginx

Questo schema a una riga previene l'errore più comune: ricaricare una configurazione rotta e mandare giù un server funzionante. Se nginx -t fallisce, il comando di ricarica non verrà eseguito.

Validazione dei file di configurazione

La causa più comune di fallimento all'avvio o comportamento imprevisto in Nginx è un errore di sintassi nei file di configurazione (nginx.conf o file inclusi in /etc/nginx/sites-available/). Nginx fornisce un'ottima utility di test integrata.

3. Test della sintassi di configurazione

Il flag -t testa i file di configurazione per errori di sintassi e verifica se i percorsi dei file di configurazione sono validi.

sudo nginx -t

Esempio di output riuscito:

nginx: il file di configurazione /etc/nginx/nginx.conf la sintassi è ok
nginx: il file di configurazione /etc/nginx/nginx.conf il test è riuscito

Esempio di output di errore:

Se esiste un errore, Nginx ti indicherà il file e il numero di riga esatti. Ad esempio, un punto e virgola mancante:

nginx: [emerg] direttiva sconosciuta "server_name example.com" in /etc/nginx/sites-enabled/default:15
nginx: il file di configurazione /etc/nginx/nginx.conf il test è fallito

Questo feedback immediato ti permette di saltare direttamente alla riga 15 del file specificato per correggere il refuso.

A volte la riga segnalata è solo dove Nginx ha finalmente notato il problema. Una } o ; mancante può essere qualche riga prima. Se l'errore punta a una direttiva dall'aspetto normale, ispeziona il blocco sopra di essa.

4. Visualizzazione della configurazione attiva

Per vedere esattamente cosa sta eseguendo Nginx (particolarmente utile dopo multiple fusioni di configurazione o include complessi), usa il flag -T (T maiuscola):

sudo nginx -T

Questo produce l'intera configurazione attiva, che può essere reindirizzata a un file per confronto o revisione dettagliata:

sudo nginx -T > current_nginx_config.txt

Fai attenzione a condividere l'output di nginx -T. Può includere nomi host interni, percorsi di certificati, header proxy e talvolta segreti passati come header. Per il lavoro sugli incidenti è eccellente. Per ticket o chat, oscura prima.

Verifica di porte e listener

Se Nginx non si avvia e i log menzionano bind() to 0.0.0.0:80 failed, un altro processo potrebbe già essere in ascolto sulla porta.

sudo ss -ltnp | grep -E ':80|:443'

L'output tipico mostra l'indirizzo locale, la porta e il nome del processo. Se Apache, Caddy, un proxy containerizzato o un vecchio processo Nginx sta occupando la porta, Nginx non può associarsi ad essa.

Puoi anche confermare il comportamento pubblico dal server stesso:

curl -I http://127.0.0.1
curl -Ik https://127.0.0.1

-I recupera solo gli header. -k ignora la validazione del certificato, utile quando si testa localhost contro un certificato emesso per un nome di dominio. Da un'altra macchina, testa anche il nome host reale:

curl -I https://example.com

Se localhost funziona ma il nome host pubblico fallisce, guarda le regole del firewall, i gruppi di sicurezza cloud, DNS, bilanciatori di carico o configurazione CDN.

Vale la pena controllare il DNS separatamente perché può far sembrare un server Nginx funzionante rotto dall'esterno:

dig +short example.com
dig +short www.example.com

Assicurati che l'indirizzo restituito sia il server o il bilanciatore di carico che ti aspetti. Se hai recentemente spostato il sito, un DNS obsoleto può inviare alcuni utenti al vecchio host mentre i tuoi test colpiscono quello nuovo.

Monitoraggio e analisi dei log

Se Nginx si avvia correttamente ma serve pagine errate o restituisce errori 5xx, i log diventano la fonte primaria di verità.

5. Individuazione dei file di log chiave

Per impostazione predefinita, i log di Nginx si trovano tipicamente in /var/log/nginx/. I due file essenziali sono:

  • access.log: Registra ogni richiesta gestita dal server, inclusi IP, ora della richiesta, codice di stato e risorsa richiesta.
  • error.log: Registra avvisi, notifiche ed errori critici incontrati durante l'operazione o l'elaborazione delle richieste.

6. Monitoraggio dei log in tempo reale con tail

Per monitorare gli errori mentre accadono, usa il comando tail con l'opzione follow (-f) sul log degli errori.

sudo tail -f /var/log/nginx/error.log

Questo è prezioso quando si testa un endpoint di applicazione appena distribuito, poiché puoi vedere immediatamente se Nginx o l'applicazione upstream stanno generando errori.

Per un server più trafficato, segui solo le nuove righe di errore e mantieni visibili i timestamp:

sudo tail -n 50 -f /var/log/nginx/error.log

Poi riproduci la richiesta fallita in un altro terminale:

curl -I https://example.com/failing/path

Questo semplice flusso di lavoro a due terminali è spesso più veloce che cliccare in un browser perché ogni richiesta e voce di log possono essere abbinate direttamente.

7. Analisi dei codici di stato del log di accesso

Per problemi di alto traffico, scansionare rapidamente il log di accesso per i codici di stato può rivelare problemi:

  • Codici 4xx (Errori del client): Spesso indicano link rotti, file mancanti (404) o problemi di permessi.
  • Codici 5xx (Errori del server): Indicano che Nginx stesso non è riuscito a soddisfare la richiesta, spesso a causa di timeout di connessione upstream (502/504) o fallimenti interni di elaborazione del server (500).

Usa grep per filtrare codici specifici. Ad esempio, trovare tutti gli errori 502 Bad Gateway:

sudo grep ' 502 ' /var/log/nginx/access.log | tail -n 20

Un rapido conteggio dei codici di stato può mostrare se hai a che fare con un singolo URL errato o un incidente più ampio:

sudo awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head

Pattern comuni:

  • Picchi di 404 spesso significano un percorso di deploy errato, file statici mancanti o route modificate.
  • 403 spesso indica permessi di file, permessi di directory o una regola di accesso intenzionale.
  • 502 di solito significa che Nginx non ha potuto ottenere una risposta valida dal servizio upstream.
  • 504 di solito significa che il servizio upstream ha accettato la connessione ma non ha risposto in tempo.

Per fallimenti upstream, controlla anche il servizio applicativo:

sudo systemctl status myapp
sudo journalctl -u myapp -n 100 --no-pager

Sostituisci myapp con il nome del servizio effettivo. Nginx può solo fare da proxy a ciò che è vivo e raggiungibile.

Diagnostica avanzata: Verbosità e ID processo

8. Forzatura del logging di debug (Attenzione consigliata)

In situazioni molto complesse, aumentare il livello di logging può rivelare informazioni più dettagliate sull'elaborazione delle richieste. Questo si fa modificando la direttiva error_log nella tua configurazione su debug.

Avvertenza: Il logging di debug genera enormi quantità di dati molto rapidamente e dovrebbe essere usato solo temporaneamente per la risoluzione attiva dei problemi, poiché influisce gravemente sulle prestazioni.

Dopo aver modificato la direttiva, devi usare reload o restart di Nginx affinché la modifica abbia effetto.

9. Trovare l'ID del processo master di Nginx (PID)

L'ID del processo (PID) è utile per inviare segnali specifici al processo master in esecuzione (ad esempio, per arresto graduale o ricarica graduale al di fuori di systemctl). Il PID è tipicamente memorizzato in un file, solitamente /var/run/nginx.pid.

cat /var/run/nginx.pid
# Esempio di output: 1234

Puoi quindi usare il comando kill se necessario (ad esempio, sudo kill -HUP 1234 per forzare una ricarica usando il PID):

La maggior parte degli operatori dovrebbe preferire systemctl reload nginx perché passa attraverso il gestore dei servizi ed è più facile da controllare. I segnali sono ancora utili su sistemi minimali, container o host più vecchi dove systemd non gestisce il processo.

Soluzioni comuni da riga di comando per sintomo

Se Nginx fallisce dopo una modifica alla configurazione:

sudo nginx -t
sudo journalctl -u nginx -n 80 --no-pager

Correggi il file e la riga segnalati, poi testa di nuovo prima di ricaricare.

Se HTTPS fallisce dopo il rinnovo del certificato:

sudo nginx -t
sudo ls -l /etc/letsencrypt/live/example.com/
sudo openssl x509 -in /etc/letsencrypt/live/example.com/fullchain.pem -noout -dates -subject

Questo conferma che il file del certificato esiste e mostra il soggetto e le date di validità.

Se i file statici restituiscono 403:

namei -l /var/www/example.com/index.html

namei -l stampa i permessi per ogni directory nel percorso. Nginx necessita del permesso di esecuzione sulle directory padre e del permesso di lettura sui file.

Se un proxy inverso restituisce 502:

sudo grep 'connect() failed' /var/log/nginx/error.log | tail
sudo ss -ltnp | grep 3000
curl -I http://127.0.0.1:3000

Questo verifica se l'upstream è in ascolto e se risponde localmente.

Se l'upstream è un socket Unix invece di una porta TCP, controlla il percorso del socket e i permessi:

sudo ls -l /run/myapp/myapp.sock
sudo grep -R "proxy_pass" /etc/nginx/sites-enabled /etc/nginx/conf.d

L'utente worker di Nginx necessita del permesso di accesso al socket. Su molti sistemi quell'utente è www-data o nginx, ma confermalo in nginx.conf prima di cambiare proprietà o gruppi.

Per fallimenti intermittenti, confronta le richieste riuscite e fallite nel log di accesso. Un piccolo campione è spesso sufficiente:

sudo grep ' 504 ' /var/log/nginx/access.log | tail -n 20
sudo grep ' 200 ' /var/log/nginx/access.log | tail -n 20

Cerca pattern nei percorsi, nei campi del tempo di risposta upstream se il formato del log li include, o un IP client specifico che sta attivando richieste pesanti.

Flusso di lavoro per la risoluzione dei problemi

Quando affronti un problema con Nginx, segui questa sequenza:

  1. Controlla lo stato: sudo systemctl status nginx.
  2. Testa la configurazione: Se non si avvia, esegui sudo nginx -t. Correggi gli errori segnalati.
  3. Riavvia/Ricarica: Se la configurazione è stata modificata, usa sudo systemctl reload nginx.
  4. Monitora i log: Se è in esecuzione ma rotto, usa sudo tail -f /var/log/nginx/error.log mentre riproduci il problema.
  5. Analizza l'accesso: Rivedi access.log per i codici di stato che indicano la natura del fallimento (4xx vs 5xx).

Questo ordine ti impedisce di indovinare. Lo stato ti dice se Nginx è in esecuzione, i test di configurazione ti dicono se può caricare, i log ti dicono cosa è successo durante le richieste reali, e i controlli locali con curl separano i problemi di Nginx da quelli upstream o di rete.

Tieni una breve nota dell'incidente mentre lavori: comando eseguito, risultato visto e modifica apportata. Previene controlli ripetuti e rende il passaggio di consegne molto più semplice.