Nginx Error 502: Bad Gateway (connect() failed: Connection refused) — Решение
При обращении к веб-сайту браузер возвращает 502 Bad Gateway. В журнале ошибок Nginx (/var/log/nginx/error.log) регистрируется событие: connect() failed (111: Connection refused) while connecting to upstream.
| Параметр Nginx | Значение | Диагноз |
|---|---|---|
upstream | 127.0.0.1:8000 / 127.0.0.1:3000 | Целевой бэкенд не запущен или слушает другой интерфейс |
| Системная ошибка | 111: Connection refused | Отказ на уровне TCP handshake (порт закрыт) |
| Статус сервиса | failed или inactive | Приложение бэкенда упало (Node.js, Go, Gunicorn, Puma) |
- Nginx работает штатно, но не может установить TCP-соединение с приложением.
- При перезапуске контейнера Docker или бэкенда ошибка временно исчезает, затем повторяется.
- Проверьте лог ошибок Nginx для выявления точного IP-адреса и порта бэкенда:
sudo tail -n 20 /var/log/nginx/error.log - Проверьте, запущен ли бэкенд-сервис и слушает ли он требуемый порт:
sudo ss -tulpn | grep -E ':(8000|3000|5000)' # Либо проверьте статус службы: sudo systemctl status <backend_service> - Убедитесь, что приложение биндится на правильный IP-адрес.
Если бэкенд слушает строго127.0.0.1, а Nginx настроен наlocalhost(который в IPv6 может резолвиться как::1), смените директиву вnginx.conf:proxy_pass http://127.0.0.1:8000; # Вместо http://localhost:8000 - Если бэкенд развернут в Docker, убедитесь, что контейнеры находятся в одной docker-сети, а
proxy_passуказывает на имя контейнера или внутренний IP:http://app_container:8000. - Проверьте локальный файрвол (iptables / ufw) и политики SELinux:
# Разрешите Nginx подключаться к сторонним портам в SELinux: sudo setsebool -P httpd_can_network_connect 1 - Перезагрузите Nginx:
sudo nginx -s reload.
localhost в директивах proxy_pass высоконагруженных систем — прямой ввод 127.0.0.1 исключает накладные расходы на DNS-резолвинг и предотвращает попытки подключения через IPv6 [::1].Частые вопросы (FAQ)
В чем разница между 502 Bad Gateway и 504 Gateway Timeout?
502 Connection Refused означает, что бэкенд сразу сбросил подключение (порт закрыт, сервис мертв). 504 Gateway Timeout означает, что соединение установилось, но бэкенд не прислал ответ за отведенное время.
Почему curl 127.0.0.1:8000 работает, а Nginx возвращает 502?
Это классический признак блокировки SELinux на RHEL/CentOS. Nginx блокируется политиками безопасности при сетевом обращении к нестандартным портам бэкенда.
Как настроить автоматический перезапуск упавшего бэкенда?
В unit-файле systemd вашего бэкенда задайте директивы Restart=always и RestartSec=3s.
Может ли Docker bridge вызывать Connection Refused?
Да, если контейнер перезапустился и получил новый внутренний IP-адрес, а Nginx закешировал старый IP.