Проксировать все запросы от Nginx к бэкэнду, за исключением одного статического файла

Проксировать все запросы от Nginx к бэкэнду, за исключением одного статического файла

Я использую Nginx для обратного проксирования API бэкенда. Однако я хотел бы, чтобы Nginx обслуживал один статический файл с именем "readme.html" при запросе к "/".

Я провел обширное исследование. Наиболее многообещающим решением показалось следующее:https://stackoverflow.com/a/15467555/2237433.

Пытаясь применить это решение к моему случаю, вот мой код. Вот мой Dockerfile:

# syntax=docker/dockerfile:1
FROM nginx:1.22.0-alpine
COPY ./nginx.conf /etc/nginx/nginx.conf
COPY ./readme.html /www/
EXPOSE 80

Когда мой контейнер Nginx запущен, я могу подключиться к оболочке и запустить ее, cat /www/readme.htmlчтобы убедиться, что файл действительно присутствует.

Вот мой nginx.conf:

# a lot of stuff
http {
    # a lot of stuff
    proxy_cache_path  /data/nginx/cache keys_zone=my-zone:10m;
    server {

        listen 80;
        add_header X-Cache-Status $upstream_cache_status always;

        location / {
            root /www/;
            try_files readme.html @backend;
        }

        location @backend {
            proxy_pass http://api:8080;
            proxy_cache my-zone;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $host;
            proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
            proxy_cache_lock on;
        }

    }
}

С этой конфигурацией все мои пути работают так, как и ожидалось, за исключением того, что когда я запускаю запрос на "/", я получаю ошибку 404. 404 на самом деле приходит с бэкенда. Вот журнал с бэкенда после запроса:

[20/Jun/2022 01:51:06] "GET / HTTP/1.0" 404 -

Таким образом, запрос «/» фактически был передан на бэкэнд.

Я перепробовал множество настроек из этой конфигурации, но безрезультатно. Спасибо за помощь!

решение1

Вы можете явно переписать URI запроса «root»:

location = / {
    root /www;
    rewrite ^ /readme.html break;
}
location / {
    proxy_pass http://api:8080;
    ...
}

Или вы можете использовать readme.htmlв качестве индексного файла:

location / {
    root /www;
    index readme.html;
    try_files $uri $uri/ @backend;
}

решение2

Я нашел работающее решение. Оказывается, location /блок должен был быть таким:

location / {
    root /www;
    try_files $uri/readme.html @backend;
}

Я не могу сказать, что действительно понимаю, почему так происходит, поэтому, если кто-то может объяснить причину этого, я буду признателен.

Связанный контент