Django+Postgres项目通过docker.yml部署时无法执行migrations问题
核心问题原因
1. Dockerfile多CMD指令冲突
Docker 镜像仅支持执行最后一个CMD指令,你配置的前两个迁移相关CMD会被直接忽略,只有runserver指令正常执行,自然没有执行数据库迁移操作。
2. 数据库启动时序不匹配
depends_on仅保证数据库容器先于服务容器启动,但Postgres容器启动后还需要数秒时间完成初始化,此时如果直接执行迁移命令会因为数据库未就绪而执行失败,也会导致表未创建。
正确配置方案
方案1:使用启动脚本执行多命令(推荐)
- 在Django项目根目录新建
entrypoint.sh启动脚本,内容如下:
#!/bin/bash # 等待Postgres数据库完全就绪,低配置环境可以调整为更长的等待时长 sleep 15 # 生成迁移文件(建议本地开发阶段执行,避免多实例启动生成重复迁移) python manage.py makemigrations # 执行数据库迁移 python manage.py migrate # 启动Django服务,必须指定0.0.0.0才能暴露到容器外 python manage.py runserver 0.0.0.0:8000 --noreload
- 本地给脚本添加执行权限:
chmod +x entrypoint.sh - 修改Dockerfile,替换原有多CMD配置:
FROM python:3.7 WORKDIR /ServerCode2/ COPY . /ServerCode2/ RUN pip install -r req.txt EXPOSE 8000 # 执行启动脚本 CMD ["/bin/bash", "entrypoint.sh"]
方案2:直接在CMD中拼接命令
如果不想新增脚本,可以直接将多个命令合并为单个CMD指令:
FROM python:3.7 WORKDIR /ServerCode2/ COPY . /ServerCode2/ RUN pip install -r req.txt EXPOSE 8000 CMD ["sh", "-c", "sleep 15 && python manage.py makemigrations && python manage.py migrate && python manage.py runserver 0.0.0.0:8000 --noreload"]
优化建议
makemigrations命令建议在本地开发阶段执行,将生成的迁移文件随代码一起打包到镜像中,容器启动阶段仅执行migrate即可,避免多实例部署时生成重复的迁移文件导致冲突。
内容的提问来源于stack exchange,提问作者Charitha Reddy
相关产品推荐
相关产品推荐

