簡體   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