Un 502 è Nginx che ti dice di aver chiesto la pagina a qualcos'altro e di aver ricevuto una risposta inservibile. Nginx stesso sta girando — se non girasse non vedresti proprio nulla — quindi il guasto sta dietro di lui, e quasi sempre è in PHP.

Capire quale dei quattro è

Leggi prima il log degli errori. Nomina la causa in una riga, e ogni minuto speso a indovinare è un minuto non speso a leggerlo.

tail -50 /var/log/nginx/error.log
  • connect() failed (111: Connection refused) — PHP-FPM non è in esecuzione.
  • upstream timed out — PHP sta girando ma ha impiegato più del tempo concesso.
  • recv() failed (104: Connection reset by peer) — il worker PHP è morto a metà richiesta, di solito per memoria esaurita.
  • no live upstreams — nel pool non è rimasto un worker per rispondere.

PHP-FPM non è in esecuzione

  1. Controlla — systemctl status php8.3-fpm — un servizio fermo lo dice già nella prima riga.
  2. Avvialo — systemctl start php8.3-fpm
  3. Scopri perché si è fermato — journalctl -u php8.3-fpm --since "1 hour ago" — una riga sbagliata nella configurazione di un pool lo ferma già all'avvio, e si fermerà di nuovo.
Se parte e si ferma subito, lancia php-fpm8.3 -t. Convalida i file dei pool e nomina la riga che non gli piace.

PHP è troppo lento per il tempo concesso

Per impostazione predefinita PHP ha 60 secondi. Un'importazione lenta o un'API esterna che ha smesso di rispondere li supera, e Nginx restituisce 502 invece di aspettare all'infinito.

location ~ \.php$ {
    fastcgi_read_timeout 300;
}
Alzare il tempo concesso nasconde il sintomo. Una pagina che richiede cinque minuti ha bisogno di una coda, non di un'attesa più lunga — e il visitatore se n'è andato molto prima.

Il worker è morto

Una richiesta che supera memory_limit uccide il proprio worker, e Nginx vede la connessione azzerata. Il log degli errori di PHP nomina il file e la riga.

grep -i "allowed memory size" /var/log/php8.3-fpm.log | tail

Il pool non ha più worker

Tutti i worker sono occupati, così una richiesta nuova non ha dove andare. È un problema di capienza, e il rimedio onesto è o meno richieste lente o più worker — ma più worker sulla stessa RAM spostano soltanto il guasto.

pm.max_children = 20
pm.max_requests = 500
Sull'hosting EGPHP il pool è gestito per te e questo caso viene risolto prima che tu lo veda. Su un VPS il dimensionamento è tuo, e il numero che conta è la tua RAM divisa per la dimensione media di un worker.