Django迁移和Docker容器

3
如何在使用Docker时处理Django迁移。
例如,在开发环境中使用容器,您拥有一个Django应用程序和其他服务,如Postgresql db容器。一切都是通过docker pull和docker-compose up完成的。大功告成!
现在,您需要添加需要更改数据库的功能。在开发环境中没有问题。您进行了一些模型更改,使用makemigrations和migrate,所有内容看起来都很好。
但是,当将新图像推送到生产环境时,您的迁移与django_tables中持久性db中的内容不匹配,因此无法运行迁移而出错。
是否有人知道如何减少这个过程中的痛苦呢?

请将您的docker-compose.yml文件和DockerFile添加到问题中。 - Satendra
2个回答

3
运行docker容器上的迁移。 假设您的compose文件如下所示:

在Docker容器上运行迁移。 假设您的compose文件如下所示:

services:
  # cointainer for django app
  app:
    build:
      context: .
      dockerfile: ./Dockerfile
    depends_on:
      - db

使用docker-compose run命令

手动运行命令,Django应用程序容器的名称为app

docker-compose run app python manage.py migrate

# use if docker compose file name is other than `docker-compose.yml` 
docker-compose -f production.yml run app python manage.py migrate

使用entrypoint.sh

每次运行容器时,自动运行。

在项目根目录下创建一个名为entrypoint.sh的文件,并将以下命令复制到其中。

python manage.py migrate --noinput

在 DockerFile 中,将项目文件夹中的 entrypoint.sh 复制到容器 app 中。
COPY ./entrypoint.sh /entrypoint.sh
RUN sed -i 's/\r//' /entrypoint.sh
RUN chmod +x /entrypoint.sh
RUN chown app /entrypoint.sh

现在有两种方法可以让entrypoint.sh自动运行

在DockerFile中提及ENTRYPOINT

ENTRYPOINT ["/entrypoint.sh"]

或者你可以在app下的command关键字中提到它,也可以在docker-compose文件中提到它。

app:
   build:
     context: .
     dockerfile: ./Dockerfile
   depends_on:
     - db
   # this will run after cointainer `up`
   command: /entrypoint.sh

2
做完了。问题出现在你的镜像中有所有的迁移。当你启动web容器时,迁移会运行,但是djang_migrations文件与你的迁移不匹配。可能会出现各种错误。应该有一个标准公式来解决这个问题,但我还没有找到。 - Mitch
2
在运行迁移时添加一些错误日志,这将有助于找出出现问题的具体原因。 - Satendra
面对与 @Mitch 相同的问题。Docker 容器中的迁移文件与本地计算机上的工作文件夹不一致。 - Muteshi
@Mitch 我知道这有点老了,但我正在认真地跳上Docker的车,你的问题是我的第一个心理障碍。仅在docker中拥有新功能X的迁移文件似乎是错误的。阅读上面的答案,似乎没有人理解它。完整的工作代码应该安全地驻留在GitHub或类似的存储库中。 - diek

3
我们已经使用Docker进行开发和生产工作超过一年了。如果我正确理解您的情况,问题在于您的生产数据库模式随着时间的推移与您的开发模式不同步。
我们采用的方法是轻松可运输地创建生产模式(包含一些测试数据)的快照,因此当您构建开发镜像时,您正在使用生产模式并根据生产模式创建迁移。当您确定要进行迁移的模式是稳定的时,请将这些迁移检入源控制。
然后,将带有保证能够干净地应用到生产模式的那些迁移的图像部署到生产环境即可。

2
从描述来看,问题可能与迁移的使用方式有关。我们使用您描述的方法,并强制规定一旦迁移已经发布到生产环境中,它就变得不可变。试图回头编辑已经发布的迁移将会导致不必要的麻烦。 - Brett Lempereur
我在PyCon上,A Lee的建议似乎是通常所做的。 - Mitch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接