如何在 nginx 上托管的单个域下托管多个烧瓶应用程序?

Posted

技术标签:

【中文标题】如何在 nginx 上托管的单个域下托管多个烧瓶应用程序?【英文标题】:How to host multiple flask apps under a single domain hosted on nginx? 【发布时间】:2016-04-14 01:17:48 【问题描述】:

我想要达到的目标:

我有一个托管 mydomain.com 的 nginx 网络服务器。当有人在他们的客户端中输入我的 domain.com 时,我希望我的服务器从/var/www/mydomain/ 提供 index.html 当他们输入 mydomain.com/flaskapp1 时,他们应该看到 flaskapp1。当他们键入 mydomain.com/flaskapp2 时,他们应该会看到 flaskapp2。

我已经设法使用http://www.markjberger.com/flask-with-virtualenv-uwsgi-nginx/ 此处的教程提供了一个或其他烧瓶应用程序,但是在尝试实现为两个单独的烧瓶应用程序提供服务时,我遇到了困难。当我尝试在浏览器中使用 mydomain.co.uk/flaskapp 或 mydomain.co.uk/flaskapp2 访问任一烧瓶应用程序时,我没有看到烧瓶应用程序,而是收到 404 消息。

这是我目前所拥有的:

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文件已经sim链接到/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

cat /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')

cat /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')

cat /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>

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

我希望这是我错过的一些简单的事情。

【问题讨论】:

但是你的问题是什么?什么不工作?有什么问题? 两个烧瓶应用程序都收到错误 404。 index.html 工作正常。 【参考方案1】:

问题就在这里:这两个烧瓶应用程序都不知道它们是从您域中的子目录提供的。 Nginx 将完整的 URL 传递给它们,而不是相对于该目录的 URL,因此每个 URL 都相对于根进行调度。让我们看看例子:

假设您的 flaskapp 中有 3 个视图,在 URL /one//two//three/ 上提供。因此,当您尝试访问 URL /one/ 上的视图时,您正在输入地址:http://yourdomain.com/flaskapp/one/。 Flask 将从 nginx URL /flaskapp/one/ 接收,但该应用程序中没有这样的视图,因此它将发送 404 作为响应。

您可以做的是通知每个flaskapp,它们不是在域根目录上提供,而是在特定子目录上提供。您可以通过发送 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;

【讨论】:

这似乎没有任何区别,但它确实为我指明了正确答案的方向,因此将其标记为有用。 也许烧瓶应用程序需要一些调整才能正确理解SCRIPT_NAME。我从来没有在烧瓶中使用过SCRIPT_NAME,但我知道这是 django 的解决方案(它可以使用相同的 nginx 和 uWSGI 配置)。【参考方案2】:

查看 NGINX 的 uwsgi 文档here。

具体来说:

不幸的是,nginx 无法相应地重写 PATH_INFO SCRIPT_NAME。出于这样的原因,您需要指示 uWSGI 映射 所谓的“挂载点”中的特定应用程序并重写 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

cat /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

现在两个烧瓶应用程序都根据需要通过 uwsgi 通过 nginx 运行。

【讨论】:

我们如何配置supervisor,使其在子域的反向代理上与nginx一起工作?【参考方案3】:

添加安装点对我有用。

/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 上托管的单个域下托管多个烧瓶应用程序?的主要内容,如果未能解决你的问题,请参考以下文章

进入我在 firebase 托管上托管的应用会重定向到谷歌登录页面

如何解决 Heroku 上托管的 django 项目中的迁移问题?

如何向地理服务器上托管的 o​​penlayers 地图添加功能?

如何在单个 AWS EC2 实例上托管多个域和子域

无法将 Azure VM 上托管的 WCF 服务引用添加到 VS2015 项目

如何将客户端的正确 IP 地址获取到 Heroku 上托管的 Node socket.io 应用程序中?