python应用部署nginx必须动静分离:静态文件由nginx直接服务(root/alias配置+强缓存),动态请求通过proxy_pass转发至127.0.0.1:8000的python进程,并设置host、x-real-ip头及300秒超时。

Python 应用部署在 Nginx 后,静态文件和动态请求必须明确分离——不是靠 Python 框架去 serve 静态资源,而是由 Nginx 直接接管,把动态请求精准转发给后端进程。核心是让 Nginx 做它最擅长的事:零拷贝发文件、高并发路由、缓存控制;让 Python 专注业务逻辑。
静态资源必须由 Nginx 直接服务
前端构建产物(如 dist/)、CSS/JS/图片、字体等,一律不经过 Python。常见错误是让 Flask 的 send_from_directory 或 FastAPI 的 StaticFiles 处理这些请求,这会严重拖慢响应、浪费 Python 进程。
- 用
root或alias显式指向静态目录,权限确保 nginx worker 用户(如www-data)可读 -
root /var/www/myapp;+location /static/→ 实际路径是/var/www/myapp/static/ -
alias /var/www/myapp/static/;+location /static/→ 实际路径就是/var/www/myapp/static/(注意结尾斜杠必须一致) - 加
try_files $uri @python_backend;,先查文件是否存在,不存在才转给 Python,这是 SPA 路由和前后端分离项目的标配 - 设置强缓存:
expires 1y;+add_header Cache-Control "public, immutable";,避免重复拉取 JS/CSS
动态请求走反向代理,不暴露 Python 进程
Python 服务(如 uvicorn 或 gunicorn)必须独立运行,绑定 127.0.0.1:8000(不能是 0.0.0.0 或 localhost),再由 Nginx 在 80/443 端口统一入口接收并转发。
-
proxy_pass http://127.0.0.1:8000/;末尾带/会剥离前缀;不带则原样转发,需与后端路由对齐 - 必加两个头:
proxy_set_header Host $host;和proxy_set_header X-Real-IP $remote_addr;,否则框架拿不到真实域名和客户端 IP - 调大超时:
proxy_read_timeout 300;(默认仅 60 秒),避免长任务触发 504 - WebSocket 支持要显式透传升级头:
proxy_http_version 1.1;+proxy_set_header Upgrade $http_upgrade;+proxy_set_header Connection "upgrade";
动静分离的典型 location 路由结构
一个清晰、无歧义的路由配置能避免路径错乱和重复转发:
- 匹配静态文件后缀:
location ~* \.(js|css|png|jpg|gif|woff2|ico|svg)$→ 直接root+expires - 匹配静态子路径:
location /assets/或location /static/→ 用alias更安全 - API 接口统一前缀:
location /api/→proxy_pass http://127.0.0.1:8000/api/; - 根路径兜底:
location /→try_files $uri $uri/ /index.html;(前端 SPA)或proxy_pass http://127.0.0.1:8000/;(纯后端服务)
排查 502 错误的关键点
502 Bad Gateway 是最常见问题,根源几乎都在后端连接环节:
- Python 进程没起来?用
netstat -tuln | grep :8000确认是否监听在127.0.0.1:8000 - Docker 网络不通?容器内 Python 绑定的是
127.0.0.1,但 Nginx 在宿主机,应改用host.docker.internal或桥接网络模式 - 连接超时?检查
proxy_connect_timeout和proxy_send_timeout是否过小 - SELinux 或防火墙拦截?临时关闭测试,确认是否为权限策略导致
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











