Come appare il messaggio
connect() failed (111: Connection refused) while connecting to upstream, client: 198.51.100.7, server: app.example.com, upstream: "http://127.0.0.1:3000/"Cause frequenti
- Il servizio backend è crashato, fermo o in riavvio.
- Il backend ascolta su un'altra porta o solo su un altro indirizzo.
proxy_passusalocalhost, che risolve in ::1, ma l'app ascolta solo su 127.0.0.1.- Container Docker fermo o porta non pubblicata.
- Dopo un deploy la config punta ancora a una porta vecchia.
Verifica
- Verifica se qualcosa ascolta sulla porta
ss -ltnp | grep -E ':3000\b' - Chiama il backend direttamente, senza nginx
curl -sv http://127.0.0.1:3000/ -o /dev/null - Mostra le destinazioni upstream nella config di nginx
nginx -T 2>/dev/null | grep -nE 'proxy_pass|fastcgi_pass|server .*:[0-9]+' - Mostra stato e ultime righe di log del servizio backend
systemctl status app.service --no-pager -l
Soluzione
- Avvia il backend e guarda nel journal perché si è fermato.
- In
proxy_passusa l'IP su cui l'app ascolta davvero, es.http://127.0.0.1:3000invece dilocalhost. - Allinea la porta tra config dell'app e nginx, poi
nginx -t && systemctl reload nginx. - Con Docker pubblica la porta con
-p 127.0.0.1:3000:3000o metti nginx nella stessa rete. - Proteggi il servizio con
Restart=on-failure, così un crash non dà 502 per ore.
Domande frequenti
Che differenza c'è con “upstream timed out (110)”?
111 significa che nessuno ascolta e la connessione viene rifiutata subito. 110 significa che il backend ascolta ma non risponde in tempo: ne risulta un 504.
Perché succede solo subito dopo un deploy?
Il servizio impiega qualche secondo ad avviarsi e nel frattempo le connessioni vengono rifiutate. Rimedio: health check prima dello switch o più istanze.