繁体   English   中英

为 static 文件提供 flask 用于开发和 nginx 用于生产

[英]Serve static files with flask on development and nginx on production

假设我有这个 mcve:

mcve.py

import textwrap
from pathlib import Path
from flask import Flask


working_dir = Path(__file__).parent
app = Flask(
    __name__,
    # static_folder=str(working_dir / "uploads"),
)


@app.route("/test")
def index():
    return textwrap.dedent(
        """
        <!DOCTYPE html>
        <html>
        <head>
            <title>Hello world</title>
        </head>
        <body>
            <img src="foo/foo.png">
            <img src="bar/bar.png">
        </body>
        </html>
    """
    ).strip()


if __name__ == "__main__":
    with app.test_client() as c:
        print(c.get("/test").data.decode("utf-8"))

运行.bat

set FLASK_APP=mcve.py
set FLASK_ENV=development
flask run

如果我在浏览器中执行run.bat然后我 go 到http://localhost:5000/test我会得到:

>flask run
 * Serving Flask app "x.py" (lazy loading)
 * Environment: development
 * Debug mode: on
 * Restarting with windowsapi reloader
 * Debugger is active!
 * Debugger PIN: 497-008-397
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
127.0.0.1 - - [31/May/2020 22:32:19] "GET / HTTP/1.1" 404 -
127.0.0.1 - - [31/May/2020 22:32:22] "GET /test HTTP/1.1" 200 -
127.0.0.1 - - [31/May/2020 22:32:22] "GET /foo/foo.png HTTP/1.1" 404 -
127.0.0.1 - - [31/May/2020 22:32:22] "GET /bar/bar.png HTTP/1.1" 404 -

问题

我应该如何修改mcve.py以使用烧瓶的服务器在开发中正确地服务器图像(现在您可以看到给出 404),然后在生产中使用 nginx 正确地为它们提供服务?

您不必为此专门配置 flask。 这些日志:

127.0.0.1 - - [31/May/2020 22:32:19] "GET / HTTP/1.1" 404 -
127.0.0.1 - - [31/May/2020 22:32:22] "GET /test HTTP/1.1" 200 -
127.0.0.1 - - [31/May/2020 22:32:22] "GET /foo/foo.png HTTP/1.1" 404 -
127.0.0.1 - - [31/May/2020 22:32:22] "GET /bar/bar.png HTTP/1.1" 404 -

实际上是由为您提供 static 内容的 werkzeug 开发服务器生成的。 当您转而使用 nginx 时,您可以使用 URL 规则拦截 GET 请求。 Flask 超级教程中的示例 nginx 配置文件:

...

server {

    ...

    location / {
        # forward application requests to the gunicorn server
        proxy_pass http://localhost:8000;
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location /static {
        # handle static files directly, without forwarding to the application
        alias /home/ubuntu/microblog/app/static;
        expires 30d;
    }
}

请注意直接处理对static的请求的/location规则,因此来自浏览器的这些请求甚至不会命中在生产中为您的 flask 应用程序提供服务的任何内容。 您可以找到更多匹配 url 的方法,例如这里 完全可以添加多个此类规则以查看不同的位置,但您需要构建应用程序以赋予这些文件一个不同的位置,以便您可以实施此类规则。


另外,要绕过当前的 404,请查看Jinja2 的模板文档并使用url_for方法确保它正确解析相对路径。

例如,如果我想包括:

<link href='static/css/bootstrap-4.3.1.min.css' rel="stylesheet">

我会改为使用:

<link href="{{ url_for('static', filename='css/bootstrap-4.3.1.min.css') }}" rel="stylesheet">

这将路径解析的责任转移给了应用程序,因此无论我遵循了多少超链接或使用了多少蓝图,在呈现模板时,此路径将始终解析为正确的static目录。

我不确定这是否适用于return textwrap.dedent因为它可能不会在模板上调用 Jinja。 您可以像这里一样为一次性示例导入render_template_string ,但render_template也可以在您的实际应用程序中使用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM