应使用 webhook 触发轻量级部署脚本:flask/fastapi 接收校验签名的 /deploy 请求,脚本中激活 venv、git pull、migrate、collectstatic,并用非 root 用户通过 systemctl --user 管理服务;secret_key 等敏感信息严禁入 git,须从安全路径或 secrets 加载。

怎么让 Django 项目在 Git Push 后自动部署到服务器
靠手动 git pull && python manage.py migrate && systemctl restart gunicorn 不现实,也容易出错。真正可行的路是用 Webhook 触发轻量级部署脚本,而不是把 CI/CD 平台(比如 GitHub Actions)直接当成部署终端 —— 它没权限操作你的生产服务器 SSH 和服务管理。
常见错误现象:Connection refused(Webhook 请求被防火墙拦)、Permission denied (publickey)(部署脚本用的 SSH key 没配对)、No module named 'django'(脚本在系统 Python 环境跑,不是项目的 venv)。
- Webhook endpoint 必须用 Flask/FastAPI 写一个极简接收器,监听
/deploy,校验X-Hub-Signature-256防伪造 - 部署脚本本身要 cd 到项目目录、source
venv/bin/activate、执行git pull origin main、python manage.py migrate --noinput、python manage.py collectstatic --noinput - gunicorn/uwsgi 进程必须用
systemctl --user或专用 deploy 用户管理,不能用 root 直接跑,否则sudo systemctl restart在 Webhook 进程里会卡住等密码 - 静态文件路径和
DEBUG=False必须提前验证好,否则collectstatic成功但 Nginx 返回 404 是最常被忽略的环节
GitHub Actions 能不能直接部署 Django 到 VPS
能,但只适合预发布环境或你完全信任该仓库的分支策略;生产环境不建议。Actions runner 没法安全持有生产服务器的私钥,硬塞进去等于把钥匙贴在门上。
使用场景:跑测试 + 构建 Docker 镜像 + 推到私有 registry,再由服务器上的 watchtower 或简单 cron 拉取更新 —— 这比裸机 SSH 部署更可控。
- 别在
secrets.SSH_PRIVATE_KEY里存解密后的私钥,要用ssh-keygen -p -P "" -N "" -f key去掉密码,否则ssh-agent加载失败 -
actions/checkout@v4默认不带 git history,而manage.py migrate在某些自定义迁移里依赖git describe,得加fetch-depth: 0 - 用
ubuntu-latestrunner 时,python manage.py compilemessages可能缺gettext,要显式run: sudo apt-get install gettext
Docker 部署 Django 时 manage.py migrate 怎么不卡住
容器启动时同步跑迁移,不是“先启应用再手工迁”,但顺序错了就会卡在数据库连接超时,或者因表不存在直接崩溃退出。
关键不是写个 wait-for-it.sh,而是让迁移成为 entrypoint 的一部分,并容忍 DB 暂不可用。
- entrypoint.sh 里用循环加
timeout 5 python manage.py dbshell -c "SELECT 1;" && break等 DB 就绪,而不是等固定秒数 -
python manage.py migrate --noinput必须放在gunicorn启动前,且加|| exit 1,否则迁移失败却继续启服务,日志里只报Relation does not exist - 别把
migrate放进 Dockerfile 的RUN阶段 —— 镜像一构建就迁,下次换数据库结构还得重做镜像 - 如果用了
django-compressor或whitenoise,collectstatic必须在 migrate 之后、gunicorn 之前,否则压缩引用的静态文件可能还没生成
为什么 Django 的 SECRET_KEY 绝对不能进 GitHub 仓库
不是“最好别放”,是只要进了,哪怕只待了五分钟,这个 Key 就应该立刻作废。它泄露意味着 session 解密、密码重置 token 伪造、甚至 django.core.signing 签名的数据(如 cookie 中的购物车)可被篡改。
真实踩坑:有人用 os.getenv('SECRET_KEY', 'dev-key-for-local'),本地开发没问题,CI 流水线里忘了设 secret,结果所有环境都 fallback 到同一个明文 dev-key,上线三天就被扫出大量伪造登录。
- 生产环境只从
/etc/secrets/django-secret-key这类只读文件读,或用 systemd 的EnvironmentFile= - GitHub Actions 里必须用
SECRET_KEY: ${{ secrets.DJANGO_SECRET_KEY }},且仓库 Settings → Secrets → Actions 里确认它是 “encrypted” 类型,不是 visible in logs - 本地开发用
.env文件,但要在.gitignore里明确写上.env,别信 “只 ignore 一行” 的模糊规则
最麻烦的其实是数据库密码和邮箱 SMTP 凭据,它们和 SECRET_KEY 一样,一旦混进 Git 历史,就得连同所有备份、CI 缓存、Docker layer 一起清理 —— 实操中很多人只改了当前配置,忘了旧镜像里还 baked 着明文。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











