代理所有来自 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 容器运行时,我可以连接到其中的 shell 并运行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:

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;
}

但我不能说我真的理解为什么,所以如果有人能解释这背后的原因,我将不胜感激。

相关内容