flask+ngix+uwsgi 没有从路由 ubuntu 20 中剥离脚本根目录

Posted

技术标签:

【中文标题】flask+ngix+uwsgi 没有从路由 ubuntu 20 中剥离脚本根目录【英文标题】:flask+ngix+uwsgi not stripping script root from route ubuntu 20 【发布时间】:2021-02-16 19:48:24 【问题描述】:

我希望有人可以帮助我。

我正在尝试将一组烧瓶应用程序从 Ubuntu 18 机器重新部署到 ubuntu 20 机器上,但它们的行为与早期部署不同。

它们已成功部署在 Ubuntu 14、16 和 18 上,包括在 Ubuntu 18 部署中从 python 2 转换为 3,但 Ubuntu 20 上的最新部署让我完全难过。

它们使用下述配置运行(在 Ubuntu 18 上成功)。在新的 Ubuntu 20 机器上部署时,flask 将路由视为脚本根目录(以及脚本根目录),这会导致 404。

目前在 U18 上工作的设置如下(nginx 简化用于在非 TLS 连接上测试)

在 :9999 上运行的应用程序不在它自己的位置,并且运行良好。

NGINX:

server 
 underscores_in_headers on;
 listen 80 default_server;
 server_name _;

 location /.well-known 
  root /var/www/html/;
 

 location / 
  include uwsgi_params;
  uwsgi_pass 127.0.0.1:9999;
 
 
 location /a 
  uwsgi_param SCRIPT_NAME /a;
  uwsgi_modifier1 30;
  include uwsgi_params;
  uwsgi_pass 127.0.0.1:10017;
 

UWSGI:

    [uwsgi]
    socket = :10017
    plugin = python3
    wsgi-file = /home/webmaster/app/run
    callable = app
    master = true
    enable-threads = true
    processes = 1
    chdir= /home/webmaster/app
    uid =  www-data
    gid = www-data

我将 404 处理程序设置为返回一些 URL 信息,而不是获取应用程序的登录页面,而是获取 404 并显示以下内容(即 nginx 正在传递给 uwsgi,并且应用程序正在运行)

网址:

http://192.168.0.250/a

输出:

url root http://192.168.0.250/a/
script root /a
request url http://192.168.0.250/a/a
request path /a
request full_path /a?

所以 url_root 和 script_root 是你所期望的,也是我们想要看到的,但是 request_url (http://192.168.0.250/a/a) 和 request_path (/a) 不是。为了让所有东西都有自己的位置,request_path 应该是“/”。

我的尝试

我提到了之前的问题,尤其是这个问题: Q: Serving flask app on subdirectory nginx + uwsgi 和这个: A: How to host multiple flask apps under a single domain hosted on nginx?

我已经尝试了这些帖子中的建议,包括以下 nginx 配置:

超级简单,要求 uwsgi 做更多事情:

location /c 
  include uwsgi_params;
  uwsgi_pass 127.0.0.1:10017;
 

使用 UWSGI:

[uwsgi]
socket = :10017
plugin = python3
wsgi-file = /home/webmaster/app/run
callable = app
master = true
enable-threads = true
processes = 1
chdir= /home/webmaster/app
uid =  www-data
gid = www-data
mount = /a=run
manage-script-name = true

这并没有解决问题

我接下来尝试重写(尝试)并欺骗 uwsgi 认为它在没有脚本根目录的情况下运行

 location /b 
  rewrite  ^/b/(.*) /$1 break;
  include uwsgi_params;
  uwsgi_pass 127.0.0.1:10017;
 

这也失败了

我也通过了上述问题讨论部分中的建议,虽然大多数工作都在修改脚本根目录,但没有人从路径中删除脚本根目录,从而启用“/start”的烧瓶路径来服务于www.app.com/a/start标识的应用

我也知道 uwsgi_modifier1 30;折旧,尽管这是这些烧瓶应用程序的第一次部署,但这是一个问题。

我还尝试根据以下问题在烧瓶端使用参数script_name=None: How can I avoid uwsgi_modifier1 30 and keep WSGI my application location-independent

但到目前为止没有任何效果,我完全被难住了。这可能很简单,但我不知道从哪里看。

最后一件事,这些应用程序以皇帝模式运行,并从命令行运行 uwsgi,无论是作为单独的 .ini 文件,还是作为皇帝文件都没有区别。

uwsgi 作为通过 apt 安装的服务运行,而不是 pip(但使用 plugin=python3 似乎可以正常运行),以防有人遇到过这个问题。

如果可能的话,我想坚持使用 apt 安装。

提前感谢任何可以提供帮助的人。

[编辑中]

这是我试图让烧瓶处理静态路由的 wsgi 文件。早该包含它,但这是一个疏忽。

谢谢

#!/usr/bin/python3
from application import app
app.config['SECRET_KEY'] = 'XXXXXXXXXX'
app.config["SESSION_COOKIE_SECURE"] = True
app.config["REMEMBER_COOKIE_SECURE"] = True
app.config["SESSION_COOKIE_HTTPONLY"] = True
app.config["REMEMBER_COOKIE_HTTPONLY"] = True
app.config['APPLICATION_ROOT'] = '/a'
app.static_url_path = '/a'
if __name__ == "__main__":
    app.run(debug = True, host= '0.0.0.0', port= 5000)

【问题讨论】:

【参考方案1】:

对于其他偶然发现此问题的人:

根据其他问题的建议使用重写,只需注意您使用的表达式是否正确。

这将失败:

 location /foo 
  rewrite  ^/foo/(.*) /$1 break;
  uwsgi_param SCRIPT_NAME /foo;
  include uwsgi_params;
  uwsgi_pass 127.0.0.1:10017;
 

因为它只适用于脚本名称“foo”,在 URL“/foo/bar”处路由“/bar”。 /foo 的根目录会失败。

这将起作用: 重写 ^/foo(.*) /$1 break;

例如

location /foo 
  rewrite  ^/foo(.*) /$1 break;
  uwsgi_param SCRIPT_NAME /foo;
  include uwsgi_params;
  uwsgi_pass 127.0.0.1:10017;
 

它将传递脚本名称,并将其从请求路径中取出,使其工作。

问题是重写中多余的“/”。

这是一个简单的错误,我花了很多时间才发现,因为我只见树木不见森林......所以我希望这可以帮助其他人。

【讨论】:

以上是关于flask+ngix+uwsgi 没有从路由 ubuntu 20 中剥离脚本根目录的主要内容,如果未能解决你的问题,请参考以下文章

uwsgi + nginx + flask:上游过早关闭

flask之路由

上游超时(uWSGI + NGINX + Flask)

从0开始在腾讯云服务器上搭建python3+flask+uwsgi+nginx服务器

手把手带你整得明明白白 Flask/Django+uWSGI+Nginx

记录一下在ubuntu 上配置nginx+uwsgi+flask出现的一点问题.