Flask 如何配置 Nginx 反向代理处理静态文件请求

文章导读
生产环境中,Nginx 应直接托管 Flask 应用的静态文件,而不是将请求反向代理给 Flask 后端。适用场景为 Flask 配合 Gunicorn/uWSGI 部署,风险边界在于 Nginx 配置的路径必须与 Flask 生成的静态 URL 前缀完全一致。
📋 目录
  1. 命令速用版
  2. 为什么会这样
  3. 分步处理
  4. 怎么验证是否生效
  5. 常见坑
  6. 常见问题
A A

生产环境中,Nginx 应直接托管 Flask 应用的静态文件,而不是将请求反向代理给 Flask 后端。适用场景为 Flask 配合 Gunicorn/uWSGI 部署,风险边界在于 Nginx 配置的路径必须与 Flask 生成的静态 URL 前缀完全一致。

先说结论:Nginx 处理静态资源能显著降低 Flask 进程负载,是标准生产部署方案。

  • 适合:Flask 应用已容器化或使用 systemd 管理,且静态文件存储在服务器本地或共享存储中。
  • 先准备:确认 Flask 项目中 static_folder 的具体物理路径,以及 Nginx 运行用户的读取权限。
  • 验收:通过 curl 请求静态文件,确认响应头 Server 字段为 nginx 且 Flask 日志无该请求记录。

命令速用版

以下是 Nginx 配置片段的核心逻辑,直接替换 server 块中的对应位置:

location /static/ {
    alias /path/to/your/project/static/;
    expires 30d;
    add_header Cache-Control "public, immutable";
}

修改配置后执行 nginx -t 检查语法,然后 systemctl reload nginx 生效。

为什么会这样

Flask 内置的开发服务器设计用于调试,不具备生产环境处理高并发静态请求的能力。Nginx 作为 Web 服务器,内核针对静态文件传输进行了优化,支持 sendfile 和异步 IO。将静态请求拦截在 Nginx 层,可以避免请求穿透到 Python 进程,减少上下文切换和 GIL 锁竞争。

分步处理

第一步:确认静态文件路径

在 Flask 应用初始化代码中查看 static_folder 参数,默认为 static,需转换为绝对路径。例如项目根目录为 /var/www/myapp,则静态路径通常为 /var/www/myapp/static

第二步:配置 Nginx location

编辑 Nginx 配置文件(通常位于 /etc/nginx/sites-available/default/etc/nginx/conf.d/ 下)。使用 alias 指令映射 URL 路径到文件系统路径。注意 alias 末尾的斜杠必须与 location 末尾斜杠对应,否则路径拼接会出错。

第三步:设置权限与所有者

确保 Nginx 运行用户(通常是 www-datanginx)对静态文件目录有读取权限。执行 chown -R www-data:www-data /path/to/static 并检查 chmod 设置。

第四步:重启服务

Flask 如何配置 Nginx 反向代理处理静态文件请求

执行 nginx -t 确认配置无误,然后重载 Nginx。如果 Flask 运行在 Gunicorn 上,无需重启 Flask,但需确保 Flask 生成的 HTML 中静态链接前缀与 Nginx location 匹配。

怎么验证是否生效

检查响应头:使用 curl -I https://yourdomain.com/static/style.css,观察 Server 字段是否显示 nginx 而非 WerkzeugGunicorn

检查访问日志:查看 Nginx 访问日志(/var/log/nginx/access.log),确认有该静态文件的 200 状态码记录。

检查 Flask 日志:监控 Flask 或 Gunicorn 的运行日志,请求静态文件时不应产生新的日志条目。如果 Flask 日志中仍有静态请求,说明 Nginx 配置未生效或请求被 proxy_pass 透传了。

常见坑

路径斜杠不匹配:location 写成 /static 而 alias 写成 /path/static/ 会导致 404。建议 location 和 alias 末尾都带上斜杠。

权限不足:Nginx 进程用户无权读取静态目录,导致 403 Forbidden。需检查文件系统权限和 SELinux/AppArmor 策略。

缓存未更新:配置了强缓存后,修改 CSS/JS 文件浏览器仍加载旧版本。需在文件名中加入哈希值或在测试阶段关闭缓存。

常见问题

配置后静态文件返回 404 怎么办?

首先检查 Nginx 错误日志 /var/log/nginx/error.log 确认具体的文件路径是否存在。多数情况是 alias 路径与实际文件系统路径不一致,或者缺少末尾斜杠导致路径拼接错误。

为什么 Flask 日志里还有静态文件请求?

这说明 Nginx 没有拦截该请求,而是通过 proxy_pass 透传给了后端。检查 Nginx 配置中 location 块的优先级,确保静态文件 location 没有被其他正则匹配覆盖。

可以使用 root 指令代替 alias 吗?

可以,但路径计算方式不同。使用 root 时,Nginx 会将 location 路径拼接到 root 路径后面。如果 location 是 /static,root 是 /var/www,Nginx 会寻找 /var/www/static。使用 alias 更适合精确映射特定目录。