结论是:Debian上Nginx+Gunicorn部署失败主因是路径、权限、用户、端口四点未对齐,90%的502或启动退出源于gunicorn二进制路径混用、proxy_pass地址不匹配、socket权限不足、systemd用户/工作目录错配及Nginx配置未启用或未重载。

直接说结论:Debian上用 Nginx + Gunicorn 跑 Python Web 应用,核心不是“能不能装”,而是“路径、权限、用户、端口”这四点没对齐,90% 的 502 Bad Gateway 或服务启动即退出都卡在这儿。
确认 Gunicorn 启动命令里 gunicorn 是哪个二进制文件
Debian 默认可能同时存在系统级和虚拟环境里的 gunicorn,混用会报 ImportError: No module named 'flask' 或找不到应用模块。
- 进你的项目虚拟环境,运行
which gunicorn,记下输出(比如/home/myapp/venv/bin/gunicorn) - 启动命令必须用这个绝对路径,不能只写
gunicorn - 检查该路径下的
python是否指向你虚拟环境的解释器:ls -l /home/myapp/venv/bin/python - 如果用
systemd管理,ExecStart=行里必须写全路径,且不能依赖PATH
Nginx 配置中 proxy_pass 必须匹配 Gunicorn 绑定的地址和端口
常见错误是 Nginx 写 http://127.0.0.1:8000,但 Gunicorn 实际监听的是 127.0.0.1:8080 或 Unix socket(如 /run/gunicorn.sock),结果直接 502。
- Gunicorn 启动时加
--bind 127.0.0.1:8080,Nginx 的proxy_pass就得严格对应http://127.0.0.1:8080 - 若用 Unix socket(推荐用于同机部署),Gunicorn 加
--bind unix:/run/gunicorn.sock,Nginx 就写proxy_pass http://unix:/run/gunicorn.sock; - socket 文件权限必须允许 Nginx 工作进程(通常是
www-data用户)读写:chown www-data:www-data /run/gunicorn.sock,且目录/run需可访问
systemd service 文件里 User 和 WorkingDirectory 必须精确
很多人把 Gunicorn 写成 root 启动,或工作目录设错,导致找不到 settings.py、读不到环境变量、静态文件路径失效。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
-
User=www-data是安全底线,绝不能用root;若应用需访问用户私有路径(如/home/myapp),则设为对应用户(如User=myapp)并确保www-data有读权限 -
WorkingDirectory=/home/myapp必须是项目根目录(含manage.py或app.py的那层),否则gunicorn myproject.wsgi:application会报 ModuleNotFoundError - 加
EnvironmentFile=/home/myapp/.env才能加载环境变量(如DJANGO_SETTINGS_MODULE),别指望 shell profile 生效 - 务必加
Restart=always和RestartSec=5,否则崩溃后服务就挂了
Debian 上 Nginx 默认不自动启用站点配置,sites-enabled 是个软链陷阱
编辑完 /etc/nginx/sites-available/myapp 后,忘了建软链或没重载,Nginx 根本不读你的配置——浏览器访问永远是默认页或 404。
- 执行
ln -sf /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/myapp(注意用-f强制覆盖) - 删掉
/etc/nginx/sites-enabled/default,避免冲突 - 每次改完配置,必须跑
nginx -t && systemctl reload nginx,光reload不校验语法会静默失败 - 查日志看是否真加载了:
tail -f /var/log/nginx/error.log,出现no live upstreams就是proxy_pass指向无效
最常被跳过的细节:Gunicorn 的 --chdir 参数和 systemd 的 WorkingDirectory 功能重叠但不等价;前者影响 Python 导入路径,后者影响整个进程上下文。两者不一致时,import myapp.settings 可能成功,但 open('static/css/app.css') 却报 FileNotFoundError——因为当前工作目录不是你认为的那个。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










