Nginx — Примеры

Пример 1 — Приложение генерирует не ту схему

Прокси завершает TLS и пересылает запрос серверу приложения внутри сети. Пользователи сообщают о цикле перенаправлений на страницах аккаунта, а лог приложения показывает, что оно перенаправляет на адрес с незащищённой схемой. Ниже — тот серверный блок, что развёрнут. Передайте исходную схему и хост, чтобы приложение строило правильные адреса.

upstream app_backend {
    server app:8080;
}

server {
    listen 443 ssl;
    server_name shop.example.test;
    location / {
        proxy_pass app_backend;
    }
}

Приходящий запрос: GET /account/settings

Решение

# добавлено внутрь существующего блока location
proxy_set_header Host              $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host  $host;
теперь ответ: 200 для /account/settings, и каждый сгенерированный адрес использует защищённую схему

TLS заканчивается на прокси, поэтому бэкенд действительно получает обычный HTTP и может построить правильную схему, только если исходная передана в заголовке. Тот же набор сообщает ему исходный хост, нужный для любого адреса, который он строит. Обычная ошибка — отлаживать в браузере, где цикл очевиден, и так и не прочитать лог приложения.

Пример 2 — Загрузка, умирающая ровно на первой минуте

Медиасервис принимает загрузки через прокси. Файлы больше нескольких мегабайт отвергаются, а более крупные, которые проходят, падают почти ровно на шестидесятой секунде, хотя приложение не пишет ошибок. Ниже — тот серверный блок, что развёрнут. Приведите лимиты в соответствие с тем, что приложение принимает, и с тем, сколько это на самом деле занимает.

upstream app_backend {
    server app:8080;
}

server {
    listen 443 ssl;
    server_name media.example.test;
    location /upload {
        proxy_pass app_backend;
    }
}

Приходящий запрос: POST /upload

Решение

# в блоке server, вне location
client_max_body_size 200m;

# внутри location /upload
client_body_timeout 300s;
proxy_read_timeout  300s;
приложение принимает 200 MB и держит запрос открытым до пяти минут
прокси теперь делает то же, а его лог записывает исход каждого POST /upload

Прокси буферизует тело и применяет свои собственные тайм-ауты, поэтому то, что клиент может отправить и сколько времени это может занять, решают его лимиты, а не лимиты приложения. Задать и то и другое из реального поведения приложения убирает оба отказа. Обычная ошибка — поднять только ограничение размера и встретить отказ на первой минуте уже на самом первом большом файле.