You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Docker容器中Flask应用配置Nginx反向代理后返回404的问题排查与解决

解决Flask + Nginx反向代理的404问题

你的问题核心非常明确:Nginx把请求的完整路径/my-app原封不动转发给了Flask,但你的Flask应用只配置了/这个根路由,自然会返回404。我们来拆解背后的原理和具体解决方案:

为什么会出现这个问题?

当你访问http://my-server.org/my-app时,Nginx的location /my-app规则会直接把请求转发到http://127.0.0.1:8080/my-app——而你的Flask应用根本没有/my-app这个路由,只有/,所以日志里才会出现GET /my-app HTTP/1.0" 404的记录。

解决方案一:让Nginx处理路径映射(最简单快速)

修改你的Nginx配置,在proxy_pass的末尾加上斜杠,这样Nginx会自动把/my-app之后的路径替换为Flask的根路径:

server {
    listen 80;
    listen [::]:80;
    server_name my-server.org;

    location /my-app {
        # 关键:末尾的斜杠会让Nginx做路径替换
        proxy_pass http://127.0.0.1:8080/;
        # 可选但建议:添加代理头让Flask获取真实客户端信息
        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;
    }
}

修改后重启Nginx生效:

sudo service nginx restart

这样配置后,访问http://my-server.org/my-app会被转发到Flask的根路径/,首页就能正常加载;访问/my-app/static/css/style.css时,会被转发到/static/css/style.css,静态文件也能正常获取。

解决方案二:让Flask感知子路径(更适合复杂应用)

如果你的应用需要生成带子路径的链接(比如用url_for生成跳转链接),或者后续要扩展路由,让Flask自己知道运行在/my-app前缀下会更可靠。

方法1:在代码中配置

直接在Flask应用代码里设置应用根路径:

from flask import Flask

app = Flask(__name__)
# 设置应用的子路径前缀
app.config['APPLICATION_ROOT'] = '/my-app'

@app.route('/')
def home():
    return "Hello from Flask!"

方法2:通过环境变量配置

启动Flask时,通过环境变量传递前缀配置:

export APPLICATION_ROOT="/my-app"
flask run --host 0.0.0.0 --port 5000

这样配置后,Flask会自动给所有路由、静态文件路径加上/my-app前缀,url_for('home')会生成/my-app/,此时Nginx的配置不需要加斜杠,直接转发即可:

location /my-app {
    proxy_pass http://127.0.0.1:8080;
    # 同样建议添加代理头
    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;
}

后续使用Gunicorn的注意事项

不管你用flask run还是Gunicorn,原理完全一致:

  • 如果用方案一(Nginx处理路径),Gunicorn的配置不需要任何变化,正常启动即可。
  • 如果用方案二(Flask感知子路径),启动Gunicorn时同样可以通过环境变量传递配置:
    APPLICATION_ROOT="/my-app" gunicorn --bind 0.0.0.0:5000 app:app
    

验证生效

修改配置后,访问http://my-server.org/my-app,你应该能看到Flask返回的首页,日志里会显示GET / HTTP/1.0" 200(方案一)或者GET /my-app HTTP/1.0" 200(方案二),静态文件也能正常加载。

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

火山引擎 最新活动