502 Bad Gateway на PHP-сайте: диагностика nginx и PHP-FPM

502 Bad Gateway на PHP-сайте обычно означает, что nginx не смог получить корректный ответ от backend-процесса. В связке nginx + PHP-FPM это часто связано с тем, что PHP-FPM не запущен, сокет недоступен, все воркеры заняты, процесс упал по памяти или запрос выполняется слишком долго.

Главная ошибка — сразу перезапускать всё без диагностики. Перезапуск может временно вернуть сайт, но причина останется.

Проверить nginx error log

Первое место — error.log nginx. Там обычно есть конкретная причина.

tail -n 150 /var/log/nginx/error.log

Типовые сообщения:

  • connect() to unix socket failed;
  • connect() failed: Connection refused;
  • upstream timed out;
  • recv() failed while reading response header from upstream;
  • no live upstreams.

Формулировка ошибки определяет следующий шаг.

PHP-FPM запущен или нет

Проверить статус сервиса:

systemctl status php8.2-fpm
systemctl status php-fpm

Название сервиса зависит от системы и версии PHP. Если сервис упал, нужно смотреть его лог.

journalctl -u php8.2-fpm -n 100 --no-pager

Сокет или порт

nginx должен обращаться туда же, где слушает PHP-FPM. Если nginx настроен на socket, путь должен существовать.

ls -la /run/php/php8.2-fpm.sock

Пример nginx:

fastcgi_pass unix:/run/php/php8.2-fpm.sock;

Если PHP-FPM слушает TCP-порт, проверяют порт:

ss -ltnp | grep 9000

После обновления PHP часто ломается именно путь к сокету: nginx всё ещё смотрит на старую версию.

Права на сокет

Если сокет существует, но nginx не имеет прав к нему подключиться, будет 502. Нужно проверить владельца и группу socket-файла и пользователя nginx.

ps aux | grep nginx
ls -la /run/php/php8.2-fpm.sock

Исправлять нужно конфигурацию пула PHP-FPM, а не chmod вручную после каждого рестарта.

Все воркеры заняты

Если PHP-FPM жив, но все дочерние процессы заняты, nginx может получать 502 или timeout. Нужно смотреть настройки pm.max_children и нагрузку.

grep -R "pm.max_children" /etc/php/*/fpm/pool.d/
ps aux | grep php-fpm

Если в логах есть server reached pm.max_children, нужно понять, почему процессы заняты: слишком мало воркеров, долгие запросы, зависшие внешние API, медленная база.

Память

PHP-процессы могут падать из-за memory_limit или нехватки памяти на сервере. Проверить:

free -m
dmesg | grep -i "killed process"
grep -R "Allowed memory size" /var/log/php* -n

Если OOM killer убивает PHP-FPM, простое увеличение max_children может сделать хуже. Нужно считать память на процесс.

Timeout

Если запрос выполняется слишком долго, nginx может оборвать ожидание. Нужно проверить fastcgi_read_timeout и request_terminate_timeout.

grep -R "fastcgi_read_timeout" /etc/nginx
grep -R "request_terminate_timeout" /etc/php/*/fpm/pool.d/

Увеличение timeout не лечит медленный код. Оно только даёт запросу больше времени. Нужно искать, почему операция занимает слишком долго.

Slowlog PHP-FPM

Для диагностики долгих запросов полезен slowlog PHP-FPM. Он показывает, где процесс зависает.

request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm-slow.log

После включения нужно повторить проблему и посмотреть лог.

Чек-лист

  1. Открыть nginx error.log.
  2. Проверить статус PHP-FPM.
  3. Проверить путь к socket или TCP-порту.
  4. Проверить права nginx на socket.
  5. Проверить pm.max_children.
  6. Проверить память и OOM killer.
  7. Проверить timeout nginx и PHP-FPM.
  8. Включить slowlog для долгих запросов.
  9. После исправления проверить логи повторно.

502 — это симптом разрыва между nginx и PHP-FPM. Чтобы исправить его надолго, нужно понять, это проблема запуска, сокета, прав, нехватки воркеров, памяти или долгого кода.

Комментарии (0)

Пока нет комментариев. Будьте первым!