【问题标题】:uWSGI: How can I mount a paste-deploy (Pyramid) app?uWSGI:如何挂载粘贴部署(金字塔)应用程序?
【发布时间】:2015-08-26 10:25:57
【问题描述】:

我有什么:

我有一个 Pyramid 应用程序,它是从 Paste ini 构建的,由 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 应用程序接收到的 uris 都以 /myapp 开头。

uWSGI 的解决方案似乎是 mount the WSGI callable on the subfolder,然后传递 --manage-script-name 选项,此时 uWSGI 应该神奇地从 uri 中去除子文件夹前缀并修复问题。

但是,我发现的文档和所有其他资源仅给出了以下形式的示例:

mount = /myapp=myapp.py

我没有包含 WSGI 可调用对象的 myapp.py,因为我的可调用对象是由 PasteDeploy 构建的。

那么,是否有可能从 Paste ini 中挂载 WSGI 可调用对象?还是我必须将 uwsgi 配置从 Paste ini 中拆分出来,并通过调用 paste.deploy.loadapp 来定义一个单独的 wsgi.py 以生成我可以挂载的 wsgi 可调用对象?

或者是否有另一种方法可以将此应用程序作为 nginx 的子文件夹提供服务,同时又不会弄乱 url 反转?

【问题讨论】:

  • 不相关,但一般来说,通过在 nginx 和 uWSGI 之间使用 UNIX 套接字连接,uWSGI 会表现得更好。请参阅blog.dscpl.com.au/2015/05/… 该帖子讨论了一个极端情况,但在更典型的情况下仍然有益。

标签: nginx pyramid uwsgi


【解决方案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

【讨论】:

【解决方案2】:

我想按照您的建议做,但这是我能找到的最接近的解决方案:如果您愿意修改您的 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 来解决原始问题...

【讨论】:

    【解决方案3】:

    从 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

    1. 围绕 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 移开,它有很多问题,而且文档缺乏很多。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-21
      • 2013-06-26
      • 2016-07-21
      • 2013-10-28
      • 1970-01-01
      • 1970-01-01
      • 2013-04-09
      • 1970-01-01
      相关资源
      最近更新 更多