You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

同一虚拟机上单Nginx实例托管两个Gunicorn Flask服务返回404求助

问题核心排查解决思路

1. 优先排查Nginx proxy_pass路径改写规则

这是该场景下最高发的配置错误,proxy_pass末尾的斜杠会直接影响转发给Gunicorn的路径:

  • 若配置为 location /myproject { proxy_pass http://unix:/tmp/myproject.sock; }:请求路径会完整传递给上游,Flask 收到的路径为 /myproject/xxx,需要你的Flask路由前缀完全匹配该路径
  • 若配置为 location /myproject { proxy_pass http://unix:/tmp/myproject.sock/; }:Nginx会自动去掉匹配到的/myproject前缀再转发,Flask收到的路径为/xxx,适合路由无前缀的Flask应用

你需要根据自己Flask应用的实际路由写法,严格对应proxy_pass的斜杠规则。


2. 配置Gunicorn SCRIPT_NAME 环境变量(推荐方案)

如果你的Flask应用本身路由无前缀(比如根路由写的是@app.route('/')),但需要对外暴露在/myproject子路径下,不需要改业务代码,直接在systemd配置中注入环境变量即可:

  • 打开对应服务的systemd配置文件,在[Service]段添加如下配置:
    # 第一个服务添加
    Environment="SCRIPT_NAME=/myproject"
    # 第二个服务对应改为 /yourproject
    
  • 修改后重载配置重启服务:
    systemctl daemon-reload
    systemctl restart myproject yourproject
    

该方案是子路径部署的标准实现,不需要调整Nginx路径改写规则。


3. 修正Nginx location匹配优先级

多location场景下容易出现匹配优先级错乱,建议给两个服务的location添加^~前缀,保证前缀匹配优先级高于正则匹配,参考配置如下:

server {
    listen 80;
    server_name 你的服务器IP或域名;

    location ^~ /myproject {
        proxy_set_header Host $http_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 http://unix:/run/myproject.sock;
    }

    location ^~ /yourproject {
        proxy_set_header Host $http_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 http://unix:/run/yourproject.sock;
    }
}

修改后验证配置合法性再重载Nginx:

nginx -t
systemctl reload nginx

4. 验证Unix套接字权限

确认两个套接字文件的权限允许Nginx进程访问:

  • 套接字文件权限建议设为775,所属组要和Nginx运行用户(通常是www-data或nginx)一致
  • 可以直接在Gunicorn启动参数中添加--umask 0002保证生成的套接字权限符合要求

5. 快速定位路径传递问题

可临时在Flask应用中添加全局钩子打印实际收到的请求路径,快速区分是Nginx转发错误还是Flask路由错误:

from flask import request

@app.before_request
def log_received_path():
    print(f"Actual path received: {request.path}")

通过Gunicorn运行日志即可确认转发的路径是否符合预期。

内容的提问来源于stack exchange,提问作者user2037606

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 20:45:04