Linux

Как исправить 502 Bad Gateway в Nginx: проверка приложения и логов

Ищем причину 502 по журналу Nginx, состоянию systemd и локальному порту. Разбираем отличие от 500/503/504 и реальный опыт остановки Node.js с последующим восстановлением.

Как исправить 502 Bad Gateway в Nginx: проверка приложения и логов

Ошибка 502 Bad Gateway в Nginx означает, что сервер, работающий посредником, не получил корректный ответ от следующего сервиса. Для сайта это может быть Node.js, Uvicorn, PHP-FPM или другой upstream. Разберём, как найти проблемный участок и проверить исправление.

Сначала определите, кто показывает ошибку

Страница 502 может прийти от вашего Nginx, внешнего CDN или балансировщика. Запишите адрес, время запроса и затронутую страницу. Посмотрите HTTP-заголовки и журнал соответствующего узла.

Если главная работает, а один API-метод отвечает 502, проверяйте маршрут этого метода. Если ошибка появляется только после выпуска новой версии, начните с изменившихся службы, порта, сокета и настроек окружения.

Не принимайте любое сообщение «сервер недоступен» за одинаковую неисправность. Код и источник ответа помогают сузить поиск.

Чем различаются 500, 502, 503 и 504

Код Что проверять в первую очередь
500 Внутреннюю ошибку того сервиса, который сформировал ответ; для приложения — его журнал
502 Доступность upstream, корректность протокола и ответа, порт или Unix-сокет
503 Режим обслуживания, доступность ресурсов или осознанный отказ обслуживать запрос; источник нужно установить
504 На каком участке ожидание upstream превысило лимит и почему ответ задерживается

Это ориентиры для диагностики, а не точный диагноз по одному числу. Приложение может само вернуть выбранный статус, а прокси — обработать его по своей конфигурации.

В нашем примере FastAPI некорректные данные получают 422. Такой ответ подтверждает, что запрос дошёл до приложения и был проверен моделью; увеличивать тайм-аут Nginx для него не требуется.

Посмотрите активную конфигурацию и журнал

Проверьте синтаксис и загруженные настройки:

sudo nginx -t
sudo nginx -T

В выводе найдите нужный server_name, его location, proxy_pass или fastcgi_pass, а также путь error_log. Полный вывод может содержать внутренние настройки: при обращении за помощью достаточно относящегося к ошибке фрагмента.

В примере Node.js используется отдельный журнал:

sudo tail -n 50 /var/log/nginx/hostfera-node.error.log

Если отдельный путь не задан, проверьте журнал из общей конфигурации, часто /var/log/nginx/error.log. Сопоставьте запись со временем вашего тестового запроса. Старое сообщение может относиться к уже устранённой проблеме.

Проверьте приложение без Nginx

Для upstream на локальном TCP-порту:

curl -i --max-time 10 http://127.0.0.1:3000/healthz
sudo ss -ltnp 'sport = :3000'
sudo systemctl status hostfera-node.service --no-pager
sudo journalctl -u hostfera-node.service -n 50 --no-pager

Замените порт, URL и имя службы на свои. Для Uvicorn из гайда FastAPI это порт 8000 и hostfera-fastapi.service.

Если прямой запрос не проходит, исправляйте запуск приложения. Проверьте путь исполняемого файла, рабочий каталог, зависимости, переменные окружения и пользователя службы. Откройте журнал ошибки до изменения лимитов Nginx.

Если приложение отвечает напрямую, сравните адрес в proxy_pass с фактическим слушателем. Также проверьте, не направляется ли HTTP на порт, который ожидает HTTPS, или наоборот.

Разберите сообщение об ошибке

connect() failed (111: Connection refused) обычно означает, что соединение к указанному адресу и порту было отвергнуто. Частые причины — остановленный процесс, другой порт или прослушивание другого адреса. Проверьте службу и ss.

No such file or directory при обращении к Unix-сокету требует проверки его пути и состояния создающей его службы. В случае PHP-FPM сравните fastcgi_pass в Nginx и listen соответствующего пула.

Permission denied у сокета требует проверки прав и пользователя Nginx. Выясните, какие права необходимы для соединения. Назначение 777 всем файлам не является подходящей заменой проверки владельца и группы.

upstream prematurely closed connection указывает на закрытие соединения до ожидаемого завершения ответа. Изучите исключения приложения, перезапуски процесса и события нехватки памяти около времени запроса.

upstream timed out требует поиска причины задержки. Это может быть долгий запрос базы, внешний API, блокирующая операция или исчерпанный пул. Прежде чем увеличивать proxy_read_timeout, определите, сколько должна длиться операция и почему она превысила этот срок.

Сообщения приведены как признаки. Они не заменяют конкретную запись вашего журнала и проверку сервиса.

Реальный опыт: остановлен Node.js

На тестовом VPS мы установили пример Node.js и настроили Nginx на 127.0.0.1:3000. Пока служба работала, запросы через Nginx возвращали 200.

Затем на стенде выполнили остановку:

sudo systemctl stop hostfera-node.service

Эта команда нужна только для воспроизведения на собственном тестовом приложении. Для диагностики рабочего сайта останавливать исправную службу не требуется.

После остановки Nginx вернул 502, а в его журнале появилась ошибка отказа соединения к 127.0.0.1:3000. Команда ss не показывала слушателя на этом порту. Причиной был отсутствующий процесс, а не сертификат, DNS или слишком короткий тайм-аут.

Фрагмент фактического журнала тестового виртуального хоста:

2026/10/29 03:27:24 [error] 32008#32008: *1240 connect() failed (111: Connection refused) while connecting to upstream, client: 127.0.0.1, server: _, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:3000/", host: "127.0.0.1:18090"
Ошибка 502 Bad Gateway на отдельном тестовом виртуальном хосте Nginx
Реальный ответ Nginx после остановки upstream Node.js

Восстановление выполнили запуском той же службы:

sudo systemctl start hostfera-node.service
curl --fail http://127.0.0.1:3000/healthz

Затем повторили запрос через Nginx: снова получен 200. Настройки тайм-аутов и правила доступа не менялись.

Когда проверять память и ограничения

Если приложение периодически исчезает, посмотрите события службы и ядра:

sudo journalctl -u hostfera-node.service --since '30 minutes ago' --no-pager
sudo journalctl -k --since '30 minutes ago' --no-pager
free -h
df -h

Не каждый занятый мегабайт означает нехватку памяти. Сопоставьте сообщение о завершении процесса с моментом ошибки. Если есть cgroup-ограничение MemoryMax, проверьте его отдельно от общей памяти VPS.

При длительных запросах измерьте время приложения и базы. Повышение числа воркеров может увеличить расход памяти. Выбор более крупного VPS имеет смысл после понимания узкого места; калькулятор ресурсов помогает начать оценку, но не заменяет наблюдение за проектом.

Как проверить исправление

Повторите тот же URL и метод запроса, который давал ошибку. Проверьте прямой upstream и внешний адрес, включая HTTPS, если он используется. Убедитесь, что исправление сохранилось после штатного перезапуска службы.

Не заменяйте 502 перенаправлением всех посетителей на главную: это скрывает причину и ломает ожидаемый результат запроса. Для пользовательской страницы ошибки можно настроить отдельное оформление, сохранив соответствующий статус.

Запишите причину и изменение: например, «служба запускалась со старым путём к Python» или «порт в proxy_pass не совпадал с портом приложения». Для общего порядка наблюдения используйте проверку сайта после запуска, а для работы с журналами — гайд о логах ошибок.

Если сбой связан с размером загрузки

При коде 413 причина другая: начните с лимита тела запроса в Nginx и приложении. Для 502 по-прежнему проверяйте upstream и его журнал.

Первоисточники

Нашли неточность?

Сообщите адрес статьи и фрагмент через контакты редакции.