在 Jenkins 流水线中自动化部署 Django,最稳妥的方式是通过 SSH 插件连接目标服务器,执行拉取代码、安装依赖、备份数据库、迁移和重启服务的脚本。此方案适合中小型团队希望减少人工干预的场景,但必须处理好权限隔离和数据安全。
先说结论:使用 Jenkins Pipeline 配合 SSH 远程执行是通用方案,重点在于权限隔离、数据库备份和回滚机制。
- 适合:已有 Jenkins 环境,希望标准化发布流程的团队
- 先准备:服务器 SSH 免密登录、sudo 免密配置、虚拟环境路径、systemd 服务配置
- 验收:部署后检查进程状态、静态文件权限及日志无报错
- 风险:直接 migrate 无备份可能导致数据丢失,需强制备份
前置环境配置
在编写流水线前,必须完成服务器端的权限和网络配置,否则流水线执行会因权限拒绝或连接失败而中断。
1. 配置 SSH 免密登录
在 Jenkins 服务器生成 SSH 密钥,将公钥添加到目标部署服务器的 authorized_keys 中。不要在 Jenkinsfile 中硬编码密码。
生成密钥命令:
ssh-keygen -t rsa -b 4096 -C "jenkins"复制公钥到目标服务器:
ssh-copy-id user@your_server_ip若无 ssh-copy-id,可手动将 ~/.ssh/id_rsa.pub 内容追加到目标服务器 ~/.ssh/authorized_keys。
2. 配置 sudo 免密权限
Jenkins 用户默认无 sudo 权限,直接执行 systemctl restart 会报错 Permission denied。需配置 visudo 允许特定命令免密。
编辑 sudo 配置:
sudo visudo添加以下内容(替换实际服务名):
jenkins ALL=(ALL) NOPASSWD: /bin/systemctl restart your_django_service此配置仅允许重启特定服务,避免赋予过高权限。
3. 数据库备份策略
迁移前务必备份数据库,防止 migrate 失败导致数据丢失不可逆。建议在脚本中集成备份命令。
MySQL 备份示例:
mysqldump -u user -p password database_name > backup_$(date +%F).sqlPostgreSQL 备份示例:
pg_dump -U user database_name > backup_$(date +%F).sqlJenkinsfile 实操配置
以下是一个基础的 Jenkinsfile 骨架,请务必根据实际路径、凭证 ID 和服务名修改。
pipeline { agent any stages { stage('Deploy') { steps { sshagent (['your-credential-id']) { sh ''' ssh user@your_server_ip " cd /path/to/project && git pull && source venv/bin/activate && pip install -r requirements.txt && # 数据库备份 mysqldump -u user -p pass db_name > backup.sql && python manage.py migrate && python manage.py collectstatic `--noinput` && sudo systemctl restart your_django_service " ''' } } } } }注意事项:
- 依赖锁定:requirements.txt 建议使用具体版本号(如 requests==2.28.0),避免自动升级导致兼容性问题。
- 路径确认:确保 venv/bin/activate 和 project 路径与实际服务器一致。
- 参数修正:collectstatic 参数为双横线 `--noinput`,不可使用反引号。
验证部署结果
部署完成后,需通过以下步骤确认服务正常运行。
1. 服务状态检查
systemctl status your_django_service确认服务处于 active (running) 状态。
2. 接口健康检查
在流水线最后增加一步 curl 请求,检查首页或健康检查接口是否返回 200 状态码。
curl -o /dev/null -s -w "%{http_code}" http://localhost:8000/health/3. 日志观察
查看应用日志和 Web 服务器日志,确认没有 ImportError 或 Database 连接错误。
常见风险与排查
1. 虚拟环境未激活
远程执行命令时,shell 可能不加载 profile,导致找不到 python 或 pip。建议在脚本中指定虚拟环境的绝对路径,或使用 source 激活。
2. 静态文件权限
collectstatic 生成的文件归属用户可能与 Nginx 读写用户不一致,导致 403 错误。确保部署用户与 Web 服务器用户权限协调,或统一设置为 www-data。
3. 数据库迁移锁表
大表迁移可能锁表导致服务不可用。建议在低峰期执行 migrate,或将迁移步骤拆分,避免长时间阻塞请求。
4. 敏感信息泄露
不要将 SECRET_KEY 或数据库密码写在代码库中。使用环境变量或 Jenkins 凭证注入到服务器环境变量中。