当容器以分离模式运行时,初始化脚本未执行

时间:2019-12-22 09:41:55

标签: django postgresql shell docker dockerfile

我有一个构建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时,此脚本可以正确运行。 (即-d命令中没有docker run标志)我通过使用psql连接到数据库容器进行了检查,并且\dt命令打印了相关的数据库。 但是,为了协调项目需要的多个容器的运行,我需要以分离模式运行它们。 (我有一个运行容器并进行连接的shell脚本)问题是,当我以分离模式运行后端容器时,未在数据库容器中创建表。

下面是CMD的Dockerfile的backend_image

CMD ["/bin/bash", "-c", "/tmp/initialization/initialize-db.sh && apachectl -D FOREGROUND"]

就像我说的那样,如果容器在前台运行,脚本将起作用,并且相关的表将在数据库容器中创建。同样,如果我通过覆盖docker run(即在命令行中指定backend_image)在CMD上使用/bin/bash命令,并在容器中手动运行脚本,它执行成功。但是以某种方式,当在带有-d标志的分离模式下运行时,该脚本似乎无法在PostgreSQL数据库中创建表。 (据我观察,通过psql连接到数据库容器并通过\dt命令打印关系)

请注意,即使后端容器以分离模式运行,apachectl命令似乎正在运行,并且服务器(以及Django应用)也可以访问。唯一的问题似乎是相关表未在数据库容器中创建。似乎初始化脚本从未在分离模式下运行,就像在容器以分离模式运行时,CMD之前的&&命令的一部分被忽略了一样。

初始化脚本有问题吗? (或者我通过CMD的Dockerfile的backend_image执行它的方式)或者我缺少分离模式的某些知识,这种分离模式使脚本无法执行?

1 个答案:

答案 0 :(得分:1)

大多数时候,我会遇到这种错误,这是因为我的数据库尚未准备好。要了解发生了什么,可以在您的Shell中登录Web服务:

docker-compose logs your-web-service -f # if you use docker-compose

这是我所有entrypoint.sh脚本中都有的一种解决方案,可以在使用数据库之前等待数据库初始化:

while ! nc -vz my_db 5432;
    do
        if [ "$MY_DB_NOT_READY_DISPLAYED" != "yes" ]
        then
            echo "my_db not ready (wait for it...)";
            MY_DB_NOT_READY_DISPLAYED="yes"
        fi
        sleep 2;
    done;
echo my_db ready;

我们尝试连接到数据库。如果可行,那就好!如果没有,我们将在数据库尚未就绪时显示,然后每2秒重试一次。

也许尝试看看数据库是否在等待您解决?在前台或后台启动的容器之间,我的行为也发生了变化。