Вопрос или проблема
Я сталкиваюсь с проблемой переписывания пути при использовании 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/
.
Детали настройки:
- Инфраструктура: Сервер Tencent Cloud (китайская облачная платформа)
- Стек: Docker Compose + обратный прокси Nginx + статический сайт Hugo
Файлы конфигурации:
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
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
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
- Ошибка 404 на
IP/Hugo-Blog/about
- Затем ошибка 404 на
IP/about
- Ошибка 404 на
-
Ожидается: Поведение, аналогичное схеме 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.