如何在NGINX上将代理转发的WSGI应用挂载到网站子目录?
问题:Flask应用挂载NGINX子路径返回404错误
我在Windows 10的WSL2(版本1.2.5.0)上使用Ubuntu 20.04.6 LTS系统,NGINX版本为1.18.0。尝试部署Flask开发的"Fibers"线程消息Web应用,用Gunicorn搭配NGINX反向代理,希望将应用挂载到已有网站的子路径localhost/fibers/,其余请求localhost/指向原有网站。两者单独设为根路径/时均可正常运行,但配置后原有网站正常,访问/fibers/返回404错误。
当前使用的NGINX配置文件:
user www-data www-data; http { include mime.types; server { listen 80; location / { root /path_to_website/src; try_files $uri $uri/ =404; index index.py index.html; } location /fibers/ { proxy_pass http://unix:/home/fiberrunner/Fibers/src/fibers.sock; } } } events {}
/var/log/nginx/error.log中仅显示NGINX重启信息,无错误提示。尝试过调换location顺序、修改子目录名称、调整路径斜杠、使用精确匹配(如location = /fibers/)等方法,问题始终存在,只有将Fibers应用配置为根路径/时才能正常运行。
疑问:最长匹配的location应该被选中,然后将匹配前缀后的剩余URI发送给proxy_pass,难道不是这样吗?
问题原因与修复方案
核心原因
NGINX反向代理时,proxy_pass的路径写法直接影响传递给后端应用的URI。当前配置中,proxy_pass指向Unix套接字但末尾没有斜杠,NGINX会把完整的请求URI(包括/fibers/前缀)传递给Flask应用,而Flask应用的路由是基于根路径/定义的,无法识别带/fibers/前缀的请求,因此返回404。
修正后的NGINX配置
user www-data www-data; http { include mime.types; server { listen 80; location / { root /path_to_website/src; try_files $uri $uri/ =404; index index.py index.html; } location /fibers/ { proxy_pass http://unix:/home/fiberrunner/Fibers/src/fibers.sock/; # 添加必要的代理头,确保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; } } } events {}
关键修改说明
proxy_pass末尾添加斜杠:添加斜杠后,NGINX会将请求中匹配/fibers/之后的部分传递给后端。比如访问/fibers/hello时,后端收到的请求是/hello,与Flask的根路由匹配。- 添加代理头:确保Flask应用能正确获取请求的主机地址、客户端IP等信息,避免因请求头缺失导致的路由或权限问题。
Flask应用侧补充配置
如果Flask应用中存在硬编码的路径(如静态文件、跳转链接),需要在应用中设置子路径前缀:
from flask import Flask app = Flask(__name__) # 设置应用的根路径前缀 app.config['APPLICATION_ROOT'] = '/fibers' # 或者使用蓝图时指定url_prefix # from flask import Blueprint # fibers_bp = Blueprint('fibers', __name__, url_prefix='/fibers') # app.register_blueprint(fibers_bp)
内容的提问来源于stack exchange,提问作者Taneli Härkönen
相关产品推荐
相关产品推荐

