Un 502, c'est Nginx qui vous dit qu'il a demandé la page à autre chose et reçu une réponse inutilisable. Nginx lui-même tourne — s'il ne tournait pas, vous ne verriez rien du tout — la faute est donc derrière lui, presque toujours dans PHP.

Reconnaître laquelle des quatre

Lisez d'abord le journal d'erreurs. Il nomme la cause en une ligne, et chaque minute passée à deviner est une minute passée à ne pas le lire.

tail -50 /var/log/nginx/error.log
  • connect() failed (111: Connection refused) — PHP-FPM ne tourne pas.
  • upstream timed out — PHP tourne mais a dépassé le délai imparti.
  • recv() failed (104: Connection reset by peer) — le processus PHP est mort en pleine requête, en général faute de mémoire.
  • no live upstreams — il ne reste plus un seul processus dans le pool pour répondre.

PHP-FPM ne tourne pas

  1. Vérifiez — systemctl status php8.3-fpm — un service arrêté le dit dès la première ligne.
  2. Démarrez-le — systemctl start php8.3-fpm
  3. Cherchez pourquoi il s'est arrêté — journalctl -u php8.3-fpm --since "1 hour ago" — une ligne fautive dans la configuration d'un pool l'arrête dès le démarrage, et il s'arrêtera de nouveau.
S'il démarre et s'arrête aussitôt, lancez php-fpm8.3 -t. Il valide les fichiers de pool et nomme la ligne qui lui déplaît.

PHP est trop lent pour le délai imparti

Par défaut, PHP dispose de 60 secondes. Un import lent ou une API externe qui a cessé de répondre dépassera ce délai, et Nginx renvoie un 502 plutôt que d'attendre indéfiniment.

location ~ \.php$ {
    fastcgi_read_timeout 300;
}
Allonger le délai masque le symptôme. Une page qui demande cinq minutes a besoin d'une file d'attente, pas d'une attente plus longue — et le visiteur est parti bien avant.

Le processus est mort

Une requête qui dépasse memory_limit tue son processus, et Nginx voit la connexion réinitialisée. Le journal d'erreurs de PHP nomme le fichier et la ligne.

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

Le pool n'a plus de processus

Tous les processus sont occupés, donc une nouvelle requête n'a nulle part où aller. C'est un problème de capacité, et le remède honnête consiste soit à réduire les requêtes lentes, soit à ajouter des processus — mais ajouter des processus sur la même mémoire ne fait que déplacer la panne.

pm.max_children = 20
pm.max_requests = 500
Sur l'hébergement EGPHP, le pool est géré pour vous et ce cas est traité avant que vous le voyiez. Sur un VPS, le dimensionnement vous revient, et le chiffre qui compte est votre mémoire divisée par la taille moyenne d'un processus.