[英]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.