將 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

您可以明確重寫“root”請求 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;
}

我不能說我真的明白為什麼,所以如果有人能解釋這背後的原因,我將不勝感激。

相關內容