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

0dxa2lsx  于 2023-01-16  发布在  Nginx
关注(0)|答案(4)|浏览(165)

我有一个 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上部署它,我想我需要再次重写所有路由。
有人有别的办法吗?

bvhaajcl

bvhaajcl1#

您需要将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;
    }
}

为长颈瓶应用程序提供枪角:一个完整的例子在这里: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)
umuewwlo

umuewwlo2#

我已经找到了一个完美的解决办法。

vc9ivgsu

vc9ivgsu3#

定义蓝图时可以使用url_prefix="/cn"选项:
https://flask.palletsprojects.com/en/2.0.x/blueprints/#nesting-blueprints

ckocjqey

ckocjqey4#

假设您希望在/api下使用Nginx托管应用程序。
首先,将URL前缀配置为locationX-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
)

另见:

P.S.如果您使用的是OpenAPI,还记得更新servers字段以指示服务器的位置。

相关问题