Nginx как reverse proxy

Почему перед приложением почти всегда стоит прокси — и как читать 502 против 504.

Зачем прокси перед приложением

Приложение слушает свой порт (скажем, 8080) только на localhost, а наружу на 80/443 смотрит nginx. Он берёт на себя то, что приложению делать не стоит:

Минимальный конфиг

server {
    listen 443 ssl;
    server_name app.example.com;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Заголовки X-Forwarded-* — не украшение: без них приложение видит все запросы приходящими со 127.0.0.1 по HTTP. Логи, rate-limiting по IP и генерация ссылок ломаются молча.

502 против 504

Две ошибки прокси, которые постоянно путают, хотя они указывают в разные стороны:

502 Bad Gateway — nginx постучался в upstream, и соединение не удалось: приложение не запущено, слушает другой порт или упало. Проверяйте процесс: ss -tlnp | grep 8080, логи приложения.

504 Gateway Timeout — соединение есть, но ответ не пришёл за proxy_read_timeout (по умолчанию 60 с). Приложение живо, но что-то в нём висит: медленный запрос к базе, внешний API, блокировка.

Правило: 502 — «не смог подключиться», 504 — «подключился и не дождался». Первое лечится на стороне процесса, второе — поиском того, что тормозит.

Не забыть перечитать

nginx -t          # проверить конфиг ДО перезагрузки
nginx -s reload   # применить без разрыва соединений

nginx -t перед каждым reload — рефлекс: сломанный конфиг при reload nginx просто не применит, а вот при рестарте — не поднимется вовсе.