nginx 不执行 python 代码,仅作反向代理和静态服务;多项目隔离靠各项目使用独立虚拟环境启动 gunicorn/uvicorn 并监听不同端口,再由 nginx 按域名(server_name)、路径(location)或端口分流,且后端启动命令必须用 venv 内绝对路径解释器。

Nginx 本身不执行 Python 代码,它只做反向代理和静态资源服务。要在一个服务器上用 Nginx 管理多个 Python 项目,关键在于:每个项目用独立虚拟环境启动专属应用进程(如 Gunicorn 或 Uvicorn),再由 Nginx 按域名、路径或端口把请求分发到对应进程——这才是真正实现多站点隔离的核心逻辑。
按域名区分:最推荐的生产方式
适合有多个独立域名的场景(如 blog.example.com、api.example.com)。Nginx 通过 server_name 匹配请求头中的 Host 字段,将流量导向不同后端。
- 每个 Python 项目在服务器上监听不同本地端口,例如:
blog 项目 → 127.0.0.1:8001
api 项目 → 127.0.0.1:8002 - 为每个域名单独建配置文件(如 /etc/nginx/sites-available/blog.conf),启用时软链到 sites-enabled/
- 配置中只需写明 proxy_pass http://127.0.0.1:8001/,其他 header 转发保持标准即可
按路径区分:同一域名下的子应用
适用于单域名多模块架构(如 example.com/admin/、example.com/api/)。注意后端应用需能识别子路径,否则重定向或静态资源会出错。
- Nginx 的 location 块必须带末尾斜杠,例如:
location /admin/ { proxy_pass http://127.0.0.1:8003/; }
这样会自动剥离 /admin/ 前缀再转发 - Django 项目需设置 FORCE_SCRIPT_NAME = '/admin'
Flask/FastAPI 应用建议用 ASGI 中间件或反向代理感知路径 - 避免遗漏 proxy_set_header X-Script-Name /admin(部分框架依赖该头)
确保 Python 进程真正隔离
虚拟环境不是摆设,必须从启动源头绑定。Nginx 配置再正确,如果后端跑错了解释器,依赖冲突立刻暴露。
- 启动命令必须用虚拟环境内的可执行文件:
/opt/myproject/venv/bin/gunicorn --bind 127.0.0.1:8001 app:app
不能只写 gunicorn(会调系统全局版本) - 用 systemd 管理时,ExecStart= 必须写绝对路径,且工作目录(WorkingDirectory=)设为项目根目录
- 验证是否生效:
ps aux | grep gunicorn 找到 PID,再运行
readlink -f /proc/PID/exe —— 输出应指向 venv/bin/python
部署时不可跳过的检查项
很多问题其实不是 Nginx 配错了,而是 Python 层没对齐。
- 确认每个项目的 venv 目录未提交 Git,但 requirements.txt 必须提交且更新及时
- 部署后手动激活 venv 并执行 pip list,核对关键包版本是否符合预期
- Nginx 日志里若出现 Connection refused,优先查对应端口的 Gunicorn 是否真在运行、监听地址是否一致
- 修改配置后务必执行 nginx -t && systemctl reload nginx,不要只重启服务
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











