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