如何使用 Nginx 在子文件夹/URL 前缀上托管 Flask 应用程序?

问题描述 投票:0回答:4

我有一个 Flask 应用程序,我想将其托管在网站的子文件夹中,例如

example.com/cn

我像这样配置我的 nginx

location /cn {
    proxy_pass http://localhost:8000/;
}

所以如果我访问

example.com/cn
,它将重定向到flask的索引页面。

但是,我已经在flask上写了其他页面的路线,如

app.route('/a')
。因此,如果我点击页面
a
的链接,URI是
example.com/a
,那么
nginx
无法将其重定向到正确的页面。

我想我可以像

app.route('/cn/a')
一样重写flask上的所有路线,但是很复杂。如果有一天我想将它部署在
example.com/en
上,我想我需要再次重写所有路由。

还有其他方法吗?

nginx flask
4个回答
3
投票

您需要将 APPLICATION_ROOT 参数添加到您的 Flask 应用程序中:

from flask import Flask, url_for
from werkzeug.serving import run_simple
from werkzeug.wsgi import DispatcherMiddleware

app = Flask(__name__)
app.config['APPLICATION_ROOT'] = '/cn'

如果您需要在服务器上托管多个应用程序,您可以配置 nginx 将所有请求重定向到由 Gunicorn 提供服务的特定 Flask 应用程序,如下所示。 (如果您的服务器仅托管一个应用程序,则没有必要)在此处了解有关gunicorn和nginx的更多信息:https://docs.gunicorn.org/en/stable/deploy.html

server {
    listen 8000;
    server_name example.com;

    proxy_intercept_errors on;
    fastcgi_intercept_errors on;

    location / {
        include proxy_params;
        proxy_pass http://unix:/path_to_example_flask_app_1/app.sock;
    }

    location /cn/{
        include proxy_params;
        proxy_pass http://unix:/path_to_example_flask_app_cn/app.sock;
    }
}

使用 Gunicorn 提供 Flask 应用程序: 完整的例子在这里:https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-gunicorn-and-nginx-on-ubuntu-18-04

#move into project directory
/path_to_gunicorn/gunicorn --workers 3 --bind unix:app.sock -m 007 run:app

如果您使用flask_restful,您也可以通过以下方式指定根路径:

from flask import Flask
from flask_restful import Api

app = Flask(__name__)
app.debug = False
api = Api(app, prefix='/cn')

api.add_resource(ResourceClass, '/example_path') #will be served when the resource is requested at path /cn/example_path

if __name__ == '__main__':
    app.run(host="0.0.0.0", port=8000)

2
投票

假设您想使用 Nginx 在

/api
下托管您的应用程序。

首先,将您的 URL 前缀配置为

location
X-Forwarded-Prefix
标头:

server {
    listen 80;
    server_name _;

    location /api {
        proxy_pass http://127.0.0.1:5000/;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Prefix /api;
    }
}

然后使用 Werkzeug 的

ProxyFix
中间件告诉 Flask 它位于代理后面:

from werkzeug.middleware.proxy_fix import ProxyFix
from flask import Flask


app = Flask(__name__)
app.wsgi_app = ProxyFix(
    app.wsgi_app, x_for=1, x_proto=1, x_host=1, x_prefix=1
)

另请参阅:

附注如果您使用 OpenAPI,还记得更新

servers
字段以指示服务器的位置。


0
投票

定义蓝图时可以使用

url_prefix="/cn"
选项:

https://flask.palletsprojects.com/en/2.0.x/blueprints/#nesting-blueprints


0
投票

这是一个很常见也很好的问题,我认为正确的答案是这里

© www.soinside.com 2019 - 2024. All rights reserved.