如何在由nginx托管的单个域名下托管多个flask应用程序?

20

我想要实现的目标:

我有一个运行在nginx web服务器上的mydomain.com。当某人在他们的浏览器中键入 mydomain.com 时,我希望我的服务器从 /var/www/mydomain/ 提供 index.html。当他们键入 mydomain.com/flaskapp1 时,他们应该看到 flaskapp1。当他们键入 mydomain.com/flaskapp2 时,他们应该看到 flaskapp2。

我已经成功地使用这里的教程 http://www.markjberger.com/flask-with-virtualenv-uwsgi-nginx/ 中的一种flask应用程序,但是在尝试实现提供两个独立的flask应用程序时遇到了困难。当我尝试通过浏览器访问 mydomain.co.uk/flaskapp 或 mydomain.co.uk/flaskapp2 时,我看到404消息而不是flask应用程序。

这是目前我所拥有的:

cat /etc/nginx/sites-available/mydomain.co.uk

server {
       listen 80;

        server_name www.mydomain.co.uk mydomain.co.uk;

        location / {
               root /var/www/html/;
               index index.html index.htm;
        }

        location /flaskapp {
                include uwsgi_params;
                uwsgi_pass unix:/tmp/flaskapp.sock;
        }

         location /flaskapp2 {
              include uwsgi_params;
              uwsgi_pass unix:/tmp/flaskapp2.sock;
         }
 }

上述conf文件已经通过符号链接的方式链接到/etc/nginx/sites-enabled目录下。

cat /etc/uwsgi/apps-available/flaskapp.ini

[uwsgi]
vhost = true
socket = /tmp/flaskapp.sock
venv = /var/www/flaskapp/venv
chdir = /var/www/flaskapp
module = flaskapp
callable = app

查看 /etc/uwsgi/apps-available/flaskapp2.ini 文件的内容

[uwsgi]
vhost = true
socket = /tmp/flaskapp2.sock
venv = /var/www/flaskapp2/venv
chdir = /var/www/flaskapp2
module = flaskapp2
callable = app

两个 .ini 文件已经通过符号链接放置在 /etc/uwsgi/apps-enabled 文件夹下。UWSGI 没有任何问题地重启并运行。flaskapp.sock 和 flaskapp2.sock 都属于 www-data 用户。

cat /var/www/flaskapp/flaskapp.py

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello World from flaskapp1!'

if __name__ == '__main__':
    app.run(host='0.0.0.0')

查看 /var/www/flaskapp2/flaskapp2.py 文件的内容

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello World from flaskapp2!'

if __name__ == '__main__':
    app.run(host='0.0.0.0')

查看 /var/www/mydomain.co.uk/index.html 文件内容

<!DOCTYPE html>
<html>
<body>

<h1>mydomain.co.uk</h1>

<p>This is the index page of my domain.co.uk</p>

</body>
</html>

两个虚拟环境都已安装 Flask,并将使用开发服务器运行 Flask 应用程序。

希望我错过的只是一些简单的东西。


1
但是你的问题是什么?哪里出了问题?有什么疑问? - GwynBleidD
2
我在两个Flask应用程序中都遇到了404错误。index.html正常工作。 - Hoppo
3个回答

13

请看这里的NGINX uwsgi文档 here.

具体来说:

不幸的是,nginx不能相应地重写PATH_INFO到SCRIPT_NAME。因此,您需要指示uWSGI在所谓的“mountpoint”中映射特定的应用程序,并自动重写SCRIPT_NAME和PATH_INFO:

更改我的flaskapp.iniflaskapp2.ini文件以包含应用程序的挂载点并打开manage-script-name变量已经起作用。

cat /etc/uwsgi/apps-available/flaskapp.ini

[uwsgi]
vhost = true
socket = /tmp/flaskapp.sock
venv = /var/www/flaskapp/venv
chdir = /var/www/flaskapp
module = flaskapp
callable = app
mount = /flaskapp=flaskapp.py
manage-script-name = true

查看/etc/uwsgi/apps-available/flaskapp2.ini文件的内容

[uwsgi]
vhost = true
socket = /tmp/flaskapp2.sock
venv = /var/www/flaskapp2/venv
chdir = /var/www/flaskapp2
module = flaskapp2
callable = app
mount = /flaskapp2=flaskapp2.py
manage-script-name = true

现在两个Flask应用程序都通过uWSGI通过Nginx运行,如要求所示。


2
我们该如何配置supervisor,以便它能够在反向代理的nginx上工作,并且在子域名上运行? - user805981

7
问题在于:这两个 Flask 应用程序不知道它们是从域的子目录中提供的。Nginx 将完整的 URL 传递给它们,而不是相对于该目录的 URL,因此每个 URL 都会相对于根目录进行调度。让我们看一个例子:
假设您的 flaskapp 中有三个视图,分别在 /one//two//three/ 的 URL 上提供服务。所以当您尝试访问 URL /one/ 的视图时,您输入的地址是:http://yourdomain.com/flaskapp/one/。Flask 将从 nginx 接收到的 URL 是 /flaskapp/one/,但该应用程序中没有这样的视图,因此它将发送 404 响应。
您可以通知每个 Flask 应用程序它们不是在域根目录上提供服务,而是在特定的子目录上提供服务。您可以通过在值中发送包含子目录位置的 SCRIPT_NAME uwsgi_param 来实现此目的,因此您的 nginx 配置将包括:
location /flaskapp {
    include uwsgi_params;
    uwsgi_pass unix:/tmp/flaskapp.sock;
    uwsgi_param SCRIPT_NAME /flaskapp;
}

location /flaskapp2 {
    include uwsgi_params;
    uwsgi_pass unix:/tmp/flaskapp2.sock;
    uwsgi_param SCRIPT_NAME /flaskapp2;
}

1
然而,这似乎没有产生任何影响,但它确实指引我找到了正确答案,所以我标记为有用。 - Hoppo
也许Flask应用程序需要进行一些微调才能正确理解SCRIPT_NAME。我从未在Flask中使用过SCRIPT_NAME,但我知道这是Django的解决方案(可以使用相同的nginx和uWSGI配置)。 - GwynBleidD

2

添加挂载点对我有用。

/etc/uwsgi/apps-available/flaskapp.ini

callable = app
mount = /flaskapp=/var/www/flaskapp

/etc/uwsgi/apps-available/flaskapp2.ini

callable = app
mount = /flaskapp2=/var/www/flaskapp2

来源 https://neginfinity.bitbucket.io/2017/09/hosting-multiple-flask-applications-in-nginx.html

本文主要介绍在Nginx中托管多个Flask应用的方法。为了实现这一目标,需要使用uWSGI及其插件,并对Nginx配置文件进行一些更改。通过本文的步骤,您将能够同时部署和管理多个Flask应用程序,并使它们可以在同一个服务器上运行。


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