Azure部署Django生产应用的数据库迁移执行方案咨询
Azure App Service 槽交换场景下Django数据库迁移方案说明
首先明确核心结论:将迁移命令写入「General settings > Startup Command」不是生产可用的正确方案,无法安全解决槽交换时的迁移不同步问题。
原有POST_BUILD_COMMAND不生效的原因
POST_BUILD_COMMAND是Azure App Service底层Oryx构建引擎在代码构建阶段执行的命令,仅在代码首次部署触发构建/重新构建时运行。槽交换操作本质是两个部署槽的流量路由规则切换,不会重新触发任何构建流程,因此交换过程中不会执行构建阶段定义的命令,这就是迁移未随版本切换执行的根本原因。
直接在Startup Command写迁移命令的风险
这种写法存在三个明确的生产风险:
- 重复执行冲突:Startup Command会在每一个应用实例启动时执行,若生产环境配置了横向扩展多实例,每个实例启动都会重复运行迁移命令,极易触发数据库表锁、迁移历史冲突,严重时会导致数据库表结构损坏。
- 无回滚缓冲:如果迁移命令执行报错,会直接导致应用实例启动失败,站点直接返回503错误,没有故障缓冲空间。
- 生产环境执行
makemigrations属于错误操作:makemigrations是本地开发阶段根据模型代码生成迁移文件的开发侧操作,迁移文件必须提前在开发环境生成、校验后提交到代码仓库随版本发布。生产环境执行makemigrations会在运行实例上生成临时迁移文件,既无法保证迁移逻辑和开发环境一致,实例重启后临时文件丢失还会导致迁移历史记录错乱。
生产环境推荐方案
所有生产方案都需要先移除所有部署配置里的python manage.py makemigrations命令,生产环境仅保留python manage.py migrate用于应用代码仓库中已提交的、经过校验的迁移文件。
方案1:CI/CD流程中执行迁移(可控性最高,优先推荐)
将迁移步骤嵌入GitHub Action工作流,放在部署到预发布槽之后、执行槽交换之前,完整流程为:
- 工作流触发构建,将新版本代码推送到Azure部署槽
- 等待部署槽应用启动完成,健康检查通过
- 在CI/CD流程中连接生产数据库,单次执行
python manage.py migrate,确认迁移执行无报错 - 迁移验证通过后,再执行槽交换操作,将新版本切到生产流量
流程中迁移步骤参考配置:
- name: Apply Django database migrations run: | pip install -r requirements.txt python manage.py migrate --settings=your_project.production_settings env: DATABASE_HOST: ${{ secrets.PROD_DB_HOST }} DATABASE_NAME: ${{ secrets.PROD_DB_NAME }} DATABASE_USER: ${{ secrets.PROD_DB_USER }} DATABASE_PASSWORD: ${{ secrets.PROD_DB_PASSWORD }} # 其余生产环境必填配置变量 - name: Swap staging slot to production uses: Azure/cli@v1 with: inlineScript: az webapp deployment slot swap --name YOUR_APP_NAME --resource-group YOUR_RESOURCE_GROUP --slot staging --target-slot production
这种方案下迁移仅执行一次,执行失败会直接中断工作流,不会触发槽交换,完全避免新版本代码和数据库结构不匹配的问题。
方案2:利用槽专属配置在预热阶段执行迁移(适合CI/CD无法直接连生产库的场景)
如果出于权限控制要求,不希望CI/CD流程持有生产数据库连接权限,可以利用Azure部署槽的「槽设置」特性实现单次迁移执行:
- 给预发布部署槽添加专属应用设置
RUN_MIGRATION=True,并将该设置标记为部署槽设置(即该配置不会随槽交换流转,永远仅在预发布槽生效) - 编写定制启动脚本替换默认启动命令,脚本逻辑为:
- 检测到存在
RUN_MIGRATION=True配置时,先执行python manage.py migrate,迁移成功后再启动Django服务 - 不存在该配置时,直接启动Django服务,不执行迁移操作
- 检测到存在
- 在槽交换配置中设置足够的预热时间,确保预发布槽在预热阶段完成迁移、通过健康检查后,再完成流量切换。
这种方案下迁移仅在预发布槽预热阶段执行一次,交换到生产的实例因为没有RUN_MIGRATION配置,启动时不会重复运行迁移,既解决了迁移时机问题,也避免了多实例重复执行的冲突。
内容的提问来源于stack exchange,提问作者corporateAbaper
相关产品推荐
相关产品推荐

