1. 1
  2. 2
  3. 3
  4. 4
  5. 5

# конспект · шаг 5 из 5

Конспект: слеш в proxy_pass

выжимка - её можно унести в заметки

Один символ в proxy_pass решает, какой URI увидит бэкенд.

Правило

Форма Что уходит бэкенду
proxy_pass http://app:8000; (без пути) URI как есть, целиком
proxy_pass http://app:8000/; (с путём) часть URI, совпавшая с location, заменяется на этот путь
location /api/  +  proxy_pass http://app:8000;      →  /api/cart
location /api/  +  proxy_pass http://app:8000/;     →  /cart
location /api/  +  proxy_pass http://app:8000/v2/;  →  /v2/cart
location /api/  +  proxy_pass http://app:8000/v2;   →  /v2cart     ← слова слиплись
location /api   +  proxy_pass http://app:8000/;     →  //cart      ← location без слеша: двойной слеш
location /api   +  proxy_pass http://app:8000/v2/;  →  /v2//cart   ← тоже двойной слеш

Подстановка буквальная: nginx заменяет совпавшую с location часть строки и не выравнивает слеши. Одиночный слеш не особый случай: если у location нет слеша на конце, остаток /cart приклеивается к / и выходит //cart (замер на 1.24 и 1.31). // пропадает только когда слеши на концах location и proxy_pass парные: location /api/ + proxy_pass …/ даёт /cart.

Как выбирать форму

  • приложение само обслуживает /api/... - префикс ему нужен, пишем без пути;
  • /api/ - твоя выдумка, а приложение слушает маршруты в корне - пишем с путём.

Соседние сервисы на одном домене

  • Запрос без последнего слеша (/grafana) nginx перенаправляет сам: 301 на /grafana/. Отдельная строка location = /grafana не нужна.
  • В этот редирект nginx подставляет свою схему и свой порт. За чужим терминатором TLS ставят absolute_redirect off, иначе клиента уводит на http:// и на внутренний порт.
  • Заголовок Location от бэкенда переписывает proxy_redirect, и умолчание работает без настройки, пока адрес совпадает с адресом из proxy_pass.

Ловушки джокера

  • Держи слеши парой. «location без слеша плюс одиночный слеш» уже даёт //cart: остаток /cart приклеивается к /. Парные концы (location /api/ + …/) дают чистый /cart.
  • Переменная в proxy_pass отменяет достройку URI. http://$backend/ шлёт бэкенду корень на любой запрос: не 404, а живая главная страница на всех адресах. Путь пишут руками через $request_uri, и нужен resolver.
  • Своё правило proxy_redirect отменяет умолчание. Починив один редирект, ломаешь те, что работали сами; лечится строкой proxy_redirect default; рядом.
  • rewrite … break перед proxy_pass отменяет замену префикса: дальше уходит то, что получилось после rewrite.
  • Ссылки внутри HTML не чинит ничто из этого - их лечит настройка публичного адреса в самом приложении (root_url, FORCE_SCRIPT_NAME, base href).

Комментарии

Пока нет комментариев. Будь первым!

Оставить комментарий

Комментарий появится после проверки. Email не публикуется. Войти, чтобы не вводить имя каждый раз.