Nginx обратный прокси удаляет префикс пути во время перенаправления с завершающим слэшем в Docker Compose и развертывании Hugo.

Вопрос или проблема

Я сталкиваюсь с проблемой переписывания пути при использовании Docker Compose с обратным прокси Nginx для развертывания блога на Hugo. Запросы к IP/Hugo-Blog/X/Y/Z перенаправляются на IP/X/Y/Z, вместо сохранения префикса /Hugo-Blog/, что приводит к ошибкам 404.
Однако, когда я пытаюсь получить доступ к IP/Hugo-Blog/X/Y/Z/ напрямую (с завершающим слешем), всё работает корректно.
Та же структура Hugo работает корректно на GitHub Pages по адресу https://ri-nai.github.io/Hugo-Blog/.

Детали настройки:

  1. Инфраструктура: Сервер Tencent Cloud (китайская облачная платформа)
  2. Стек: Docker Compose + обратный прокси Nginx + статический сайт Hugo

Файлы конфигурации:

  1. docker-compose.yaml:
version: '3'
services:
  homepage: # Стартовая страница, работает нормально
    ...
  blog:
    build: ./Hugo-Blog
    container_name: blog
    expose:
      - "80"
    restart: always

  reverse-proxy:
    image: nginx:stable-alpine
    container_name: reverse-proxy
    volumes:
      - ./nginx-proxy/default.conf:/etc/nginx/conf.d/default.conf:ro
    ports:
      - "80:80"
    depends_on:
      - homepage
      - blog
    restart: always
  1. Hugo-Blog/Dockerfile:
FROM hugomods/hugo:exts-0.128.0 AS builder
COPY . .
RUN hugo --minify --baseURL "https://ri-nai.github.io/Hugo-Blog/"

FROM nginx:stable-alpine
COPY --from=builder /src/public /usr/share/nginx/html
  1. nginx-proxy/default.conf:
server {
    listen 80;
    server_name IP;

    location /Hugo-Blog/ {
        proxy_pass blog:80/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    location / {
        proxy_pass homepage:80/;
        # ... такие же заголовки
    }
}

Попытки устранения неполадок:

  • Подтверждено, что конфигурация Hugo работает правильно на GitHub Pages

  • Проверено, что контейнеры Docker работают и доступны внутри сети

Попытки и ожидания

  • Запрос к IP/Hugo-Blog/about

    1. Ошибка 404 на IP/Hugo-Blog/about
    2. Затем ошибка 404 на IP/about
  • Ожидается: Поведение, аналогичное схеме 301 → 200 на GitHub Pages, с сохранением префикса /Hugo-Blog/

Ответ или решение

Конфигурация развертывания вашего проекта с использованием Docker Compose, Nginx в качестве обратного прокси и Hugo для генерации статических страниц имеет проблему, связанную с переписыванием пути при работе с редиректами с завершающим слэшем. Ваше решение корректно работает на GitHub Pages, но вызывает ошибки 404 в текущей инфраструктуре при попытке доступа без завершающего слэша. Давайте детально разберем эту ситуацию и предложим возможное решение.

Теория

Обратный прокси-сервер (Nginx в вашем случае) часто используется для маршрутизации запросов внутри инфраструктуры, расположенной за прокси. Обычной задачей для такого сервера является корректное переписывание URL путей, чтобы пользователи могли без проблем обращаться к нужным сервисам. В вашем случае, Nginx используется для маршрутизации запросов между разными контейнерами в Docker, каждый из которых обслуживает разные компоненты приложения.

Проблема заключается в том, что когда пользователь обращается по URL, не оканчивающемуся на слэш, Nginx должен переадресовать запрос на URL с завершающим слэшем. При этом может теряться часть пути из-за специфической настройки параметров, таких как proxy_pass, в конфигурации Nginx.

Пример

Работа вашей текущей конфигурации следующая: когда поступает запрос на IP/Hugo-Blog/X/Y/Z, Nginx должен перенаправить его на контейнер blog, сохраняя при этом префикс /Hugo-Blog/. Однако в конфигурации:

location /Hugo-Blog/ {
    proxy_pass blog:80/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
}

использование proxy_pass blog:80/; может быть причиной того, что префикс теряется. Это связано с тем, что proxy_pass в такой форме переписывает путь, исключая часть, после совпадения с location.

Применение

Чтобы решить данную проблему, необходима корректировка конфигурации Nginx. Один из способов — отсутствие завершающего слэша в proxy_pass. Например:

location /Hugo-Blog/ {
    proxy_pass http://blog:80;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
}

В этом случае Nginx не будет переписывать URI и удалять часть пути. Дополнительно можно использовать директиву trailing_slash и rewrite для управления редиректами и обеспечения корректной работы с завершающими слэшами:

location /Hugo-Blog {
    rewrite ^(/Hugo-Blog)(/.*)?$ $1$2/ permanent;
}

location /Hugo-Blog/ {
    proxy_pass http://blog:80;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
}

Добавление вышеуказанного блока должно помочь настроить автоматическое перенаправление запросов без завершающего слэша к просмотру содержимого с завершающим слэшем, сохраняя при этом правильную структуру URL.

Кроме того, убедитесь, что в вашем Hugo проекте корректно настроено использование basePath. Если baseURL проекта настроен на поддиректорию (например, /Hugo-Blog/), важно, чтобы это отражалось в самом контенте сайта и путях к статическим ресурсам.

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

Следуя этим советам, вы сможете добиться правильной маршрутизации запросов и избежать ошибок 404, связанных с потерей части пути в URL.

Оцените материал
Добавить комментарий

Капча загружается...