【发布时间】:2019-12-22 09:41:55
【问题描述】:
我有一个构建 Django 环境的 Dockerfile,它基于 Ubuntu 映像并运行 Apache HTTP Server。 (httpd) 我们称该图像为backend_image。连同另一个 PostgreSQL 数据库容器,我计划使用这个镜像作为开发环境,启动两个容器并使用--network 标志来连接它们。
我计划在backend_image 中有一个初始化脚本,它会在后端容器运行时创建相关表。该脚本的内容对于 Django 应用来说是相当标准的,如下所示。
#!/bin/bash
source ${VIRTUAL_ENV_DIR}/bin/activate
python ${SCRIPT_LOCATION} makemigrations library
python ${SCRIPT_LOCATION} migrate
deactivate
当我在前台运行backend_image 时,此脚本运行正确。 (即在docker run 命令中没有-d 标志)我通过使用psql 连接到数据库容器来检查它,并且\dt 命令打印了相关数据库。
但是,为了编排项目所需的多个容器的运行,我需要以分离模式运行它们。 (我有一个运行容器并连接它们的 shell 脚本)问题是,当我以分离模式运行后端容器时,不会在数据库容器中创建表。
下面是backend_image的Dockerfile的CMD。
CMD ["/bin/bash", "-c", "/tmp/initialization/initialize-db.sh && apachectl -D FOREGROUND"]
就像我说的,如果容器在前台运行,则脚本可以工作,并且在数据库容器中创建相关表。同样,如果我通过覆盖CMD(即在命令行上指定/bin/bash)在backend_image 上使用docker run 命令并从容器内手动运行脚本,它会成功执行。但不知何故,当以 -d 标志在分离模式下运行时,脚本似乎没有在 PostgreSQL 数据库中创建表。 (据我观察,通过psql 连接到数据库容器并通过\dt 命令打印关系)
请注意,apachectl 命令似乎正在运行,并且服务器(以及 Django 应用程序)似乎可以访问,即使后端容器以分离模式运行也是如此。唯一的问题似乎是未在数据库容器中创建相关表。似乎初始化脚本从未在分离模式下运行,就好像当容器在分离模式下运行时,&& 之前的 CMD 命令的一部分被忽略了。
是初始化脚本的问题吗? (或者我通过 backend_image 的 Dockerfile 的 CMD 执行它的方式)或者我在分离模式方面缺少什么,这会阻止脚本被执行?
【问题讨论】:
-
如果应用程序在数据库完全准备好之前启动,通常会发生这样的问题;这有可能吗?如果在初始化脚本中添加
set -x使其出错退出,它真的运行成功了吗?
标签: django postgresql shell docker dockerfile