同一进程托管多应用(Flask、Nginx、uWSGI)挂载点路径异常求助
这个问题我之前部署多应用时也踩过坑,核心原因是你用了硬编码的绝对路径(带/开头的/home)——浏览器会直接把它解析为域名根目录下的路径,完全忽略当前页面所在的/myproject子路径。下面给你几个靠谱的解决办法:
1. 用Flask原生的url_for生成链接(最推荐)
这是Flask为这类场景设计的标准方案,能自动适配你的挂载路径。把模板里的硬编码链接替换成url_for调用:
<a href="{{ url_for('home') }}">HOME</a>
这里的home是你Flask应用里对应/home路由的视图函数名(比如@app.route('/home')装饰的那个函数的名字)。
配套配置确保路径正确
为了让url_for知道你的应用挂载在/myproject下,你可以二选一:
- 在Flask应用里设置
APPLICATION_ROOT:app = Flask(__name__) app.config['APPLICATION_ROOT'] = '/myproject' - 或者启动uWSGI时加上挂载参数和管理脚本名的参数:
uwsgi --mount /myproject=myapp:app --manage-script-name
这样url_for生成的链接就会自动带上/myproject前缀,变成myserver.com/myproject/home。
2. 避免硬编码绝对路径(不推荐,仅适合简单场景)
如果你不想用url_for,可以把链接开头的/去掉,改成相对路径:
<a href='home'>HOME</a>
但要注意:这种方法只适合所有页面都在同一层级的情况,如果你的页面在/myproject/home/detail,相对路径home会指向/myproject/home/home,反而会出错,所以不推荐在复杂应用里用。
3. 配置Nginx传递正确的SCRIPT_NAME(辅助优化)
在Nginx的反向代理配置里,加上uwsgi_param传递SCRIPT_NAME,让Flask能正确识别自己的挂载路径:
location /myproject { include uwsgi_params; uwsgi_param SCRIPT_NAME /myproject; uwsgi_pass unix:/path/to/your/uwsgi.sock; }
配合uWSGI的--manage-script-name参数,Flask会自动基于SCRIPT_NAME调整所有路由和链接的前缀。
总结
最稳妥的方案是用url_for生成所有链接,再配合正确配置APPLICATION_ROOT或者传递SCRIPT_NAME,这样不管你后续怎么调整挂载路径,链接都不会出错,完全不用手动修改模板里的路径。
内容的提问来源于stack exchange,提问作者JMY

