如何将proxy_passed WSGI应用程序“挂载”到NGINX上网站的子目录中?

How can I "mount" a proxy_passed WSGI application onto a subdirectory of a website on NGINX?

提问人:Taneli Härkönen 提问时间:10/27/2023 更新时间:11/6/2023 访问量:12

问:

我在 Windows 10 上的 WSL2 版本 1.2.5.0 上的 Ubuntu 2.0.6 LTS 上使用 NGINX 版本 2.18.0

我一直在尝试了解部署 WSGI 应用程序。我用 flask 构建了一个小型线程消息传递 Web 应用程序,我称之为“Fibers”,并想尝试在我的本地网络上使用 Gunicorn 在 NginX 反向代理后面提供它。我尝试构建配置文件,以便将光纤应用程序“挂载”到我之前构建的现有网站上的特定子路径。因此,与“localhost/fibers/”匹配的所有内容都将与 fibers-application 匹配,而其他所有内容都将与“localhost/”等正常站点匹配。当配置为 nginx.conf 上的根“/”位置时,这两个站点都可以很好地工作。但是,我无法使配置按照描述工作。

这是我尝试过的最新nginx.conf文件。

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 {}

我让网站正常响应“/”,但“/fibers”子目录上的 Web 应用程序给我一个 404 未找到。

我尝试浏览文章、视频和 stackoverflow 帖子,但找不到答案或线索发生了什么。除了我的 nginx 重启消息外,别无他物。我搜索了 NGINX 文档并开始使用,但帮助了 puckall,并且对学习他们的技术非常敌视。/var/log/nginx/error.log

在根“/”下配置时,这两个站点都处于工作状态。

我期望可以在子目录“/fibers/”上访问光纤应用程序,并且可以在根目录“/”上访问该站点。

我尝试切换它们的位置,尝试更简单的子目录名称,尝试在位置端点上使用不同的斜杠组合,尝试使用等于 siqn 的 siqn,例如 .以下是一些示例:location = /fibers/

location /fibers/
location /fibers
location = /fibers/
location = /fibers

还尝试将其与浏览器端的不同 url 匹配。但是每次根网站都可以工作,但子目录应用程序不能。

但是一旦我将纤维应用程序设置为root,就可以了

location / {
    proxy_pass http://unix:/home/fiberrunner/Fibers/src/fibers.sock;
}

..它开始工作。

我没有得到什么?是否应该选择最长的匹配位置,然后在匹配的前缀设置为proxy_pass后发送剩余的$URI?

nginx 网页 WSGI

评论


答:

0赞 Taneli Härkönen 11/6/2023 #1

在大卫·卢克什(David Lukeš)的大力帮助下,找到了我自己问题的答案。他在这里 https://dlukes.github.io/flask-wsgi-url-prefix.html 写了一篇非常详细和详尽的文章。

简而言之:如果你用 url_for() 形成了每个内部链接,你可以为 gunicorn 设置一个环境变量 SCRIPT_NAME=/url_prefix,gunicorn 会从每个传入请求的路径开头剥离它,并将其添加到每个内部链接的前面。

如果您的系统使用 systemd 作为 init/PID1 进程,则可以在您正在创建的 gunicorn-service 的 unit 文件中添加一个包含 linux 上环境变量的文件。在 /etc/systemd/system/.service 文件中的 [service] 部分下,可以将 “EnvironmentFile” 变量设置为您创建的包含 “SCRIPT_NAME” 变量的环境变量文件的路径。因此,您的单元文件如下所示:

[Unit]
Description=Gunicorn instance to serve Flask app
After=network.target

[Service]
User=username
Group=www-data
WorkingDirectory=/home/username/Project/src
**EnvironmentFile=/home/username/Project/gunicorn_env_vars**
ExecStart=/home/username/Project/.venv/bin/gunicorn --workers 3 --bind unix:project.sock -m 007 wsgi:app

[Install]
WantedBy=multi-user.target

和环境变量文件(此处为“gunicorn_env_vars”)如下所示:

PATH=/home/fiberrunner/poista/fiber_test/Fibers/.venv/fiber_venv/bin
**SCRIPT_NAME=/fibers**

希望这也能帮助其他人