通过 Docker Compose 使用 Gunicorn 和 Nginx 运行的 Flask 应用程序提供服务/但对于其他路由返回 404

问题描述 投票:0回答:1

问题:

我正在尝试通过 Nginx 提供 Flask 应用程序(与 Gunicorn 一起运行)。我的项目是使用容器设置的,并使用 Docker Compose 进行编排。我已编辑

nginx.conf
来服务我的应用程序。

我面临的问题是我可以访问 Flask 应用程序的

/
路径,但是当我尝试导航到应用程序中的任何其他链接时,我收到
404 Not Found
错误。

Nginx 日志

nginx-1  | 172.25.0.1 - - [22/May/2024:15:57:42 +0000] "GET / HTTP/1.1" 200 5086 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:126.0) Gecko/20100101 Firefox/126.0"

nginx-1  | 2024/05/22 15:57:49 [error] 30#30: *1 open() "/usr/share/nginx/html/dataset_detail/1" failed (2: No such file or directory), client: 172.25.0.1, server: localhost, request: "GET /dataset_detail/1?page=1 HTTP/1.1", host: "0.0.0.0", referrer: "http://0.0.0.0/"

nginx-1  | 172.25.0.1 - - [22/May/2024:15:57:49 +0000] "GET /dataset_detail/1?page=1 HTTP/1.1" 404 153 "http://0.0.0.0/" "Mozilla/5.0 (X11; Linux x86_64; rv:126.0) Gecko/20100101 Firefox/126.0"

nginx.conf

events {
    worker_connections 1024;
    multi_accept on;
}
http {
    server {
        listen 80;
        server_name localhost;
        # Serve static files directly if possible
        location /static {
            alias /usr/share/nginx/html/static;
        }
        # Additional static file directories
        location /docs {
            alias /usr/share/nginx/html/docs;
            index index.html;
        }
        location /dataset {
            alias /usr/share/nginx/html/dataset;
            autoindex on;
        }
        # Handle Flask app routes
        location / {
            try_files $uri $uri/ @flask;
        }
        location @flask {
            proxy_pass http://app:5000;
            proxy_redirect off;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_pass_request_body on;
        }
    }
}

附加信息

  • 我的 Flask 应用程序的根路由
    /
    工作正常并返回预期的页面。
  • 其他路线,例如
    /dataset_detail/1
    ,会返回
    404 Not Found
    错误。
  • Nginx 似乎正在尝试从
    /usr/share/nginx/html
    目录提供这些路由,而不是将请求传递给 Flask 应用程序。

问题:

什么可能导致 Nginx 正确服务根路由,但对其他路由返回 404 错误?如何配置 Nginx 将所有请求正确转发到 Flask 应用程序?

docker flask nginx reverse-proxy
1个回答
0
投票

问题在于,默认情况下,nginx 位置块使用“前缀匹配”策略。

来自文档

位置可以由前缀字符串或正则表达式定义。正则表达式使用前面的“~*”修饰符(对于不区分大小写的匹配)或“~”修饰符(对于区分大小写的匹配)来指定。为了找到与给定请求匹配的位置,nginx 首先检查使用前缀字符串(前缀位置)定义的位置。其中,选择并记住具有最长匹配前缀的位置。然后按照正则表达式在配置文件中出现的顺序进行检查。正则表达式的搜索在第一个匹配处终止,并使用相应的配置。如果未找到与正则表达式匹配的内容,则使用之前记住的前缀位置的配置。

因此,

location /dataset
将请求与
/dataset_detail/1
相匹配,查找静态文件并在未找到时返回 404。

我不确定适合您的特定应用程序的最佳解决方案是什么,但您可能可以使用

location
正则表达式匹配器来更准确地检测已知/良好的静态文件,或者可能使用
try_files
重定向到
@flask
如果找不到静态文件。

© www.soinside.com 2019 - 2024. All rights reserved.