Come diagnosticare e risolvere gli errori Nginx 502 Bad Gateway
Nginx è un web server e reverse proxy potente e popolare, spesso utilizzato per servire contenuti statici, bilanciare il traffico e inoltrare richieste a vari server applicativi upstream come PHP-FPM, Node.js, Python Gunicorn o Apache Tomcat. Quando Nginx riscontra un problema nella comunicazione con uno di questi server upstream, solitamente risponde con un errore "502 Bad Gateway".
Questo articolo fornisce una guida completa, passo dopo passo, per comprendere, diagnosticare e risolvere gli errori Nginx 502 Bad Gateway. Esploreremo le cause comuni, ti forniremo tecniche pratiche di risoluzione dei problemi utilizzando strumenti da riga di comando e offriremo soluzioni attuabili per ripristinare rapidamente i tuoi servizi web. Che tu sia un amministratore di sistema, uno sviluppatore o gestisca il tuo server, questa guida ti aiuterà ad affrontare efficacemente uno degli errori Nginx più comuni.
Comprendere l'Errore Nginx 502 Bad Gateway
Un errore 502 Bad Gateway indica che Nginx, agendo come reverse proxy, ha ricevuto una risposta non valida da un server upstream. Significa che Nginx si è connesso con successo a un server upstream ma non ha ricevuto alcuna risposta, una risposta incompleta o una risposta che non ha potuto comprendere. Fondamentalmente, il problema non è con Nginx stesso, ma con il servizio con cui Nginx sta cercando di comunicare.
I server upstream comuni includono:
- PHP-FPM: Per applicazioni PHP (ad es. WordPress, Laravel).
- Gunicorn/uWSGI: Per applicazioni Python (ad es. Django, Flask).
- Node.js: Per applicazioni JavaScript.
- Apache Tomcat: Per applicazioni Java.
- Altri web server: Come Apache HTTP Server che serve contenuti specifici.
L'errore 502 è un indicatore cruciale che il backend della tua applicazione non funziona correttamente o è inaccessibile a Nginx.
Diagnosi Passo Dopo Passo
La chiave per risolvere un errore 502 è una diagnosi sistematica. Inizia con i colpevoli più probabili e indaga progressivamente.
1. Controlla Prima i Log degli Errori di Nginx
I log degli errori di Nginx sono la fonte primaria di informazioni. Spesso contengono dettagli specifici sul motivo per cui Nginx non è riuscito a comunicare con il server upstream.
- Posizione: Tipicamente si trova in
/var/log/nginx/error.log. - Comando: Usa
tail -fper monitorare i log in tempo reale mentre tenti di riprodurre l'errore.
tail -f /var/log/nginx/error.log
Cosa cercare:
* connect() failed (111: Connection refused): Indica che il server upstream non è in ascolto sull'indirizzo/porta specificata o che un firewall sta bloccando la connessione.
* upstream timed out: Il server upstream ha impiegato troppo tempo per rispondere.
* upstream prematurely closed connection: Il server upstream ha chiuso la connessione prima di inviare una risposta completa.
* no live upstreams while connecting to upstream: Nginx non è riuscito a trovare server upstream configurati disponibili.
2. Verifica lo Stato del Server Upstream
Una volta che hai indizi dai log degli errori di Nginx, controlla lo stato del tuo server applicativo upstream.
-
Per PHP-FPM:
bash systemctl status phpX.X-fpm # Sostituisci X.X con la tua versione di PHP, ad es. php7.4-fpm sudo service phpX.X-fpm status -
Per Node.js/Python/Altre App Personalizzate:
Controlla se il processo è in esecuzione.bash ps aux | grep node ps aux | grep gunicorn
Se stai usando un gestore di processi come PM2 (Node.js) o Supervisor (generale), controlla il suo stato.bash pm2 status sudo supervisorctl status
Se il servizio non è in esecuzione, prova ad avviarlo e controlla i suoi log per eventuali errori.
systemctl start phpX.X-fpm
# Oppure
sudo service phpX.X-fpm start
3. Controlla la Connettività di Rete verso l'Upstream
Assicurati che Nginx possa raggiungere il server upstream sulla porta o sul percorso del socket configurato.
-
Per connessioni TCP/IP (ad es.
127.0.0.1:8000):
Usatelnetonc(netcat) per testare la connettività della porta dal server Nginx.bash telnet 127.0.0.1 8000 nc -vz 127.0.0.1 8000
Una connessione riuscita dovrebbe mostrareConnected to 127.0.0.1.osucceeded!. Se si blocca o mostraConnection refused, il servizio upstream non è in ascolto o un firewall lo sta bloccando. -
Per socket Unix (ad es.
unix:/run/php/phpX.X-fpm.sock):
Verifica che il file del socket esista e abbia le autorizzazioni corrette.bash ls -l /run/php/phpX.X-fpm.sock
Nginx dovrebbe avere i permessi di lettura/scrittura su questo file socket. L'utente Nginx (ad es.www-data) deve far parte del gruppo proprietario del socket (ad es.www-dataophp-fpm).
Cause Comuni e Soluzioni
Basandoti sui tuoi passaggi diagnostici, ecco le cause più frequenti degli errori 502 e come risolverle.
1. Server Upstream Non in Esecuzione o Bloccato
Causa: L'applicazione a cui Nginx sta cercando di fare proxy (ad es. PHP-FPM, Gunicorn, app Node.js) non è in esecuzione o si è bloccata.
Soluzione: Avvia o riavvia il servizio upstream.
# Esempio per PHP-FPM
systemctl start phpX.X-fpm
# Se è già in esecuzione e sospetti un crash, riavvialo:
systemctl restart phpX.X-fpm
# Per applicazioni personalizzate, usa i loro comandi specifici di avvio/riavvio
Suggerimento: Assicurati che i tuoi servizi upstream siano configurati per avviarsi automaticamente all'avvio del sistema. Per i servizi systemd, usa systemctl enable phpX.X-fpm.
2. Sovraccarico del Server Upstream / Esaurimento Risorse
Causa: Il server upstream è sopraffatto, sta esaurendo memoria, CPU o sta raggiungendo i limiti di processo, causando il mancato funzionamento della risposta o il rifiuto di nuove connessioni.
Sintomi: I log degli errori di Nginx potrebbero mostrare connection refused o upstream timed out in modo intermittente, specialmente sotto carico. Gli strumenti di monitoraggio di sistema (top, htop, free -h) mostrano un elevato utilizzo delle risorse.
Soluzioni:
-
Per PHP-FPM: Modifica le impostazioni del pool di PHP-FPM nel suo file di configurazione (ad es.
/etc/php/X.X/fpm/pool.d/www.conf).pm.max_children: Il numero massimo di processi figli che possono essere attivi contemporaneamente.pm.start_servers: Il numero di processi figli creati all'avvio.pm.min_spare_servers,pm.max_spare_servers: Controllano quanti processi figli inattivi vengono mantenuti.
ini ; Esempio per la gestione dinamica dei processi pm = dynamic pm.max_children = 50 pm.start_servers = 10 pm.min_spare_servers = 5 pm.max_spare_servers = 20
* Aumentamemory_limitinphp.inise gli script stanno esaurendo la memoria.
* Per altre applicazioni: Aumenta il numero di processi worker, thread o alloca più memoria se possibile. Monitora le metriche specifiche della tua applicazione.
* Timeout di Nginx: Aumenta le direttiveproxy_connect_timeout,proxy_send_timeouteproxy_read_timeoutnella configurazione di Nginx, ma comprendi che questo ritarderà l'errore se il backend è veramente in difficoltà.nginx http { ... proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; ... }
3. Configurazione Upstream Errata in Nginx
Causa: Nginx è configurato per connettersi all'indirizzo IP, alla porta o al percorso del socket Unix errato per il server upstream.
Sintomi: I log degli errori di Nginx mostrano connect() failed (111: Connection refused) immediatamente dopo una richiesta.
Soluzione: Rivedi attentamente la configurazione del blocco server di Nginx (/etc/nginx/sites-available/your_site.conf).
-
Per upstream HTTP/HTTPS:
nginx location /app { proxy_pass http://127.0.0.1:8000; # Assicurati che IP e porta siano corretti proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } -
Per PHP-FPM tramite socket Unix:
nginx location ~ \.php$ { fastcgi_pass unix:/run/php/phpX.X-fpm.sock; # Verifica che questo percorso corrisponda esattamente alla configurazione di PHP-FPM fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } -
Per PHP-FPM tramite TCP/IP:
nginx location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; # Verifica IP e porta fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; }
Dopo aver apportato modifiche, testa sempre la tua configurazione Nginx e ricarica/riavvia Nginx:
nginx -t
systemctl reload nginx # O restart se -t indica una necessità
4. Superamento di request_terminate_timeout di PHP-FPM
Causa: Uno script PHP impiega più tempo per l'esecuzione rispetto all'impostazione request_terminate_timeout in PHP-FPM. Nginx attende la risposta, ma PHP-FPM termina lo script, causando la ricezione di una risposta incompleta da parte di Nginx.
Sintomi: I log degli errori di Nginx potrebbero mostrare upstream timed out o script timed out. I log di PHP-FPM potrebbero mostrare child XX exited on signal 9 (SIGKILL).
Soluzione:
* Aumenta request_terminate_timeout: Nella configurazione del tuo pool PHP-FPM (www.conf), trova e modifica questa direttiva. Impostarla a 0 disabilita il timeout, ma generalmente non è raccomandato poiché gli script a lunga esecuzione possono bloccare le risorse.
```ini
request_terminate_timeout = 300 # Aumenta a 5 minuti (300 secondi)
```
-
Aumenta
fastcgi_read_timeoutin Nginx: Questo timeout di Nginx dovrebbe essere uguale o superiore arequest_terminate_timeout.nginx location ~ \.php$ { ... fastcgi_read_timeout 300s; # Deve essere >= request_terminate_timeout di PHP-FPM ... }
Attenzione: Mentre aumentare i timeout può risolvere l'errore 502, potrebbe mascherare problemi di prestazioni sottostanti. La soluzione migliore a lungo termine è ottimizzare lo script PHP lento.
5. Problemi con il Firewall
Causa: Un firewall (sul server Nginx o sul server upstream, se sono separati) sta bloccando le connessioni alla porta o al socket upstream.
Soluzione:
* Controlla lo stato del firewall:
```bash
sudo ufw status # Per UFW (Ubuntu/Debian)
sudo firewall-cmd --list-all # Per firewalld (CentOS/RHEL)
sudo iptables -L # Per iptables
```
-
Apri le porte necessarie: Assicurati che la porta utilizzata da Nginx per connettersi all'upstream (ad es. 9000 per PHP-FPM tramite TCP/IP) sia aperta.
bash sudo ufw allow from 127.0.0.1 to any port 9000 # Permetti al localhost di connettersi alla porta 9000 sudo firewall-cmd --permanent --add-port=9000/tcp # Per firewalld sudo firewall-cmd --reload
* Disabilita temporaneamente il firewall a scopo di test solo in un ambiente controllato, quindi riabilitalo e configurarlo correttamente.
6. Interferenza di SELinux o AppArmor
Causa: Miglioramenti di sicurezza come SELinux (su RHEL/CentOS) o AppArmor (su Ubuntu/Debian) potrebbero impedire a Nginx di accedere al socket upstream o di effettuare connessioni di rete, anche se i permessi dei file e i firewall sono configurati correttamente.
Sintomi: I log potrebbero mostrare messaggi come permission denied o simili, specialmente in /var/log/audit/audit.log (per SELinux).
Soluzione:
* Controlla audit.log:
```bash
sudo grep nginx /var/log/audit/audit.log
```
- Imposta temporaneamente SELinux in modalità permissiva:
sudo setenforce 0. Se l'errore si risolve, SELinux è il colpevole. Dovrai quindi generare e applicare le policy SELinux appropriate (ad es.audit2allow). Ricorda di reimpostarlo su enforcing (sudo setenforce 1). - Controlla lo stato di AppArmor:
sudo aa-status. Se AppArmor è attivo, potresti dover modificare il profilo Nginx.
7. Body di Richiesta/Risposta di Grandi Dimensioni (Proxy Buffering)
Causa: Le impostazioni di proxy buffering predefinite di Nginx potrebbero essere troppo piccole per body di richiesta o risposta molto grandi, causando la chiusura anticipata della connessione.
Sintomi: I log degli errori di Nginx potrebbero mostrare upstream prematurely closed connection while reading response header from upstream o upstream prematurely closed connection while reading response body from upstream.
Soluzione: Modifica le direttive di proxy buffering di Nginx nel tuo blocco http, server o location.
http {
...
proxy_buffer_size 128k; # Dimensione del buffer per la prima parte della risposta
proxy_buffers 4 256k; # Numero e dimensione dei buffer per il resto della risposta
proxy_busy_buffers_size 256k; # Dimensione massima dei buffer occupati
proxy_temp_file_write_size 256k; # Dimensione per la scrittura su file temporanei se il buffering va oltre i limiti
...
}
Nota: Queste impostazioni consumano più memoria. Modificale con cautela in base alle risorse del tuo server e alla dimensione tipica delle risposte della tua applicazione.
Suggerimenti Generali per la Risoluzione dei Problemi
- Rivedi tutti i log pertinenti: Oltre ai log degli errori di Nginx, controlla anche i log di accesso di Nginx, i log delle applicazioni upstream (log di PHP-FPM, Gunicorn, app Node.js) e i log di sistema (
/var/log/syslog,dmesg). - Riavvia Nginx: Dopo qualsiasi modifica alla configurazione, riavvia sempre Nginx per assicurarti che vengano applicate:
systemctl restart nginx. - Testa la Configurazione di Nginx: Prima di riavviare, valida la sintassi della tua configurazione Nginx:
nginx -t. - Isola il Problema: Prova a bypassare Nginx e ad accedere direttamente all'applicazione upstream. Ad esempio, se la tua app Node.js è su
localhost:3000, usacurl http://localhost:3000dalla riga di comando del server. Se anche questo fallisce, il problema è sicuramente con la tua applicazione, non con Nginx. - Controlla lo Spazio su Disco: Un disco pieno può impedire alle applicazioni di scrivere file temporanei o log, causando crash o fallimenti. Usa
df -hper controllare l'utilizzo del disco.
Conclusione
Gli errori Nginx 502 Bad Gateway sono comuni ma puntano quasi sempre a un problema con l'applicazione backend a cui Nginx sta cercando di connettersi, non a Nginx stesso. Controllando sistematicamente i log degli errori di Nginx, verificando lo stato del server upstream, confermando la connettività di rete e quindi affrontando problemi comuni di configurazione o di risorse, puoi diagnosticare e risolvere efficacemente questi problemi.
Ricorda di affrontare la risoluzione dei problemi in modo metodico, iniziando dai controlli più basilari e approfondendo progressivamente. Testa sempre la configurazione di Nginx dopo aver apportato modifiche e monitora la salute della tua applicazione e del tuo server per prevenire future occorrenze. Con queste strategie, sarai ben attrezzato per mantenere i tuoi servizi funzionanti senza intoppi.