uWSGI:如何挂载paste-deploy(Pyramid)应用程序?

6

我的情况:

我有一个基于Paste ini构建的Pyramid应用程序,由uWSGI提供服务并由nginx代理。它运行良好。以下是nginx配置:

server {
    listen 80;
    server_name localhost;
    access_log /var/log/myapp/nginx.access.log;
    error_log /var/log/myapp/nginx.error.log warn;

    location / {
        uwsgi_pass localhost:8080;
        include uwsgi_params;
    }
}

这里是 uWSGI ini 配置文件:

[uwsgi]
socket = 127.0.0.1:8080
virtualenv = /srv/myapp/venv
die-on-term = 1
master = 1
logto = /var/log/myapp/uwsgi.log

这个配置位于Pyramid的production.ini文件中,因此我使用以下命令来提供应用程序:

uwsgi --ini-paste-logged production.ini

所有这些都能正常工作。

我想要做的事情:

只需要一个简单的变化。我想将此应用程序作为子文件夹提供,而不是作为根目录提供。我希望从http://localhost提供服务,而是从http://localhost/myapp提供服务。

现在一切都坏了

如果我将nginx的location指令从/更改为/myapp/myapp/,我会收到404错误,因为WSGI应用程序接收到的URI都以/myapp开头。

uWSGI的解决方案似乎是在子文件夹上挂载WSGI可调用对象,然后传递--manage-script-name选项,此时uWSGI应该自动从URI中删除子文件夹前缀并修复问题。

但是,我找到的所有文档和资源都只给出了以下形式的示例:

mount = /myapp=myapp.py

我没有一个包含WSGI可调用的myapp.py,因为我的可调用正在由PasteDeploy构建。
因此,是否可以从Paste ini中挂载WSGI可调用?还是说我需要将uwsgi配置拆分出Paste ini,并定义一个单独的wsgi.py,并调用paste.deploy.loadapp生成一个可以挂载的WSGI可调用?
或者还有其他方法可以从nginx的子文件夹中提供此应用程序,而不会弄乱URL反向?

1
无关的事情,但通常情况下,使用UNIX套接字连接nginx和uWSGI会使uWSGI的性能更好。请参阅http://blog.dscpl.com.au/2015/05/effects-of-yielding-multiple-blocks-in.html。该文章讨论了极端情况,但在更典型的情况下也很有益处。 - Graham Dumpleton
3个回答

1

我在从Python2切换到Python3后,在部署中遇到了这个问题。

  1. 在Python2中,我使用了uwsgi_modifier1 30;技巧,但是在Python3中不再起作用,如此描述:https://github.com/unbit/uwsgi/issues/876

  2. 它的文档非常糟糕(根本没有?我是通过阅读uWSGI源代码了解的),但是--mount选项接受以下语法:

--mount=/app=config:/path/to/app.ini

请注意:使用--mount选项时,您还需要--manage-script-name选项。
它还存在其他问题:https://github.com/unbit/uwsgi/issues/2172 3.编写一个包装脚本来部署Paste-Deploy应用程序非常简单,这也是我现在的部署方式。
from paste.script.util.logging_config import fileConfig as configure_logging
from paste.deploy import loadapp as load_app
from os import environ

config_file = environ['INI_FILE']

configure_logging(config_file)
application = load_app('config:' + config_file)

将其保存为例如app.py,然后您可以使用--mount /app=app.py来使用它,INI_FILE环境变量应该指向您的.ini文件。

顺便说一句 - 我考虑远离uWSGI,它很有缺陷,文档也很缺乏。


0

我想按照你的建议去做,但这是我能找到的最接近的解决方案:如果你愿意修改你的PasteDeploy配置,你可以按照以下步骤操作:http://docs.pylonsproject.org/docs/pyramid/en/1.0-branch/narr/vhosting.html

将[app:main]重命名为[app:mypyramidapp]并添加一个新的部分:

[composite:main]
use = egg:Paste#urlmap
/myapp = mypyramidapp

我还需要将这个添加到我的nginx配置中:

uwsgi_param     SCRIPT_NAME '';

并安装粘贴模块

sudo pip3 install paste

我想知道是否有一种方法可以像最初提出的问题那样“挂载”PasteDeploy...

-1

是的,使用Nginx作为子目录挂载Pyramid绝对是可行的。你需要使用uWSGI中的Modifier1选项,如下所示:

location /myapp {
    include uwsgi_params;
    uwsgi_param SCRIPT_NAME /myapp;
    uwsgi_modifier1 30;
    uwsgi_pass localhost:8080;
}

30 的神奇值告诉 uWSGI 在请求中从 PATH_INFO 的开头删除 SCRIPT_NAME 参数。Pyramid 接收请求并正确处理它。

只要您使用标准的 Pyramid 机制在应用程序中生成 URL 或路径,SCRIPT_NAME 就会自动合并,这意味着所有链接/资源等的 URL 都是正确的。

文档不是很清楚,但有关可用修饰符的更多信息,请参见:https://uwsgi-docs.readthedocs.org/en/latest/Protocol.html


它不适用于Python3,并且实际上已经被弃用:https://github.com/unbit/uwsgi/issues/876 - Code Painters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接