如何通过Github Actions连接DigitalOcean托管数据库执行迁移并保留回滚功能?
解决方案
方案1:用DigitalOcean App Platform内置执行迁移(推荐,完美适配回滚需求)
这是最贴合你需求的方案,不需要处理IP白名单,还能自动触发回滚:
- 把你的Django应用和PostgreSQL数据库放在同一个DigitalOcean项目下,开启私有网络(DigitalOcean默认允许同私有网络内的资源互相访问,无需公网IP白名单)
- 在App Platform的应用配置里,找到「启动命令」或者「部署命令」设置项,填入迁移命令:
python manage.py migrate --noinput(加--noinput避免交互) - 如果你需要先执行其他操作(比如收集静态文件),可以写一个启动脚本
start.sh,内容如下:
然后把启动命令设为#!/bin/bash python manage.py migrate --noinput python manage.py collectstatic --noinput gunicorn your_project.wsgi:application --bind 0.0.0.0:$PORT./start.sh(记得给脚本加执行权限,Dockerfile里加RUN chmod +x start.sh) - 这样每次部署时,App Platform会先执行迁移,一旦迁移失败,整个部署流程会自动回滚到上一个可用版本,完全符合你的回滚需求
方案2:用静态IP代理Github Actions流量(适合必须在CI里跑迁移的场景)
如果一定要在Github Actions里执行迁移,可以通过固定代理IP绕过动态IP问题:
- 在DigitalOcean申请一个静态IP,创建一个小型Droplet作为代理服务器(比如用Nginx做反向代理,或者Squid)
- 把这个静态IP加入PostgreSQL数据库的白名单
- 在Github Actions的工作流中,配置所有数据库相关的请求通过这个代理转发(比如设置环境变量
HTTP_PROXY、HTTPS_PROXY为代理IP) - 这样不管Github Actions的IP怎么变,都是通过固定的代理IP访问数据库,就能解决连接被拒的问题
方案3:临时动态调整DB白名单(应急用,不推荐)
这个方案有安全风险,但可以应急:
- 在Github Secrets里存储你的DigitalOcean API Token
- 在Github Actions工作流中,先调用DigitalOcean的API临时将
0.0.0.0/0加入数据库白名单:doctl auth init --access-token $DO_API_TOKEN doctl databases db update <你的数据库ID> --allow-list 0.0.0.0/0 - 执行迁移命令
- 最后再通过API移除临时规则,恢复原来的白名单(一定要加
finally步骤,避免迁移失败后DB一直开放)
注意事项
- 不管用哪个方案,都要确保Django的数据库配置正确:用私有网络的连接字符串(如果用方案1),或者公网连接字符串+正确的白名单(方案2/3)
- 方案1中,App Platform的迁移是部署流程的一部分,迁移失败会直接终止部署并回滚,这是最省心的方式
内容的提问来源于stack exchange,提问作者Nex
相关产品推荐
相关产品推荐

