Nginx proxy_pass: правильное проксирование, URI, заголовки и WebSocket
proxy_pass выглядит просто, но одна из самых частых ошибок Nginx — неверное понимание того, как меняется URI при наличии или отсутствии завершающего слеша.
Простой reverse proxy
location /api/ {
proxy_pass http://127.0.0.1:8080;
}В таком варианте исходный URI передаётся backend почти как есть.
proxy_pass с URI
location /api/ {
proxy_pass http://127.0.0.1:8080/;
}Здесь часть URI, совпавшая с location, заменяется URI из proxy_pass. Именно из-за этой разницы часто появляются двойные или потерянные префиксы.
Передаём исходный Host и IP
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;Backend должен доверять этим заголовкам только от вашего reverse proxy, иначе клиент сможет подделать исходный IP.
WebSocket
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
location /socket/ {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_pass http://127.0.0.1:3000;
}HTTPS до backend
Если upstream использует HTTPS, не отключайте проверку сертификата просто ради устранения ошибки. Настройте доверенный CA и SNI, если backend ожидает имя хоста.
Таймауты
Не увеличивайте proxy_read_timeout до огромных значений как универсальное решение. Сначала выясните, почему backend отвечает долго.
Проверка
nginx -t
systemctl reload nginx
curl -I https://example.com/api/