成功等待脚本后如何启动 docker 容器

Posted

技术标签:

【中文标题】成功等待脚本后如何启动 docker 容器【英文标题】:How to start docker container after succesfull wait-for-it script 【发布时间】:2017-02-13 03:09:10 【问题描述】:

在启动其他应用程序之前,我正在使用等待它的脚本来检查数据库是否已启动。

#!/bin/bash

set -e

host="$1"
shift
cmd="$@"

until psql -h "$host" -U "postgres" -c '\l'; do
  >&2 echo "Postgres is unavailable - sleeping"
  sleep 1
done

>&2 echo "Postgres is up - executing command"
exec $cmd

我找到了这个脚本here。 现在我的应用程序容器停止运行mysql is up - executing command。 所以脚本是成功的(db 正在运行),但我不清楚如何执行我的应用程序的 dockerfile 中的真正 CMD(在脚本之后)。

这是我的 dockerfile 的结尾:

COPY docker-entrypoint.sh /entrypoint.sh
COPY ./wait-for-it.sh wait-for-it.sh
ENTRYPOINT ["/entrypoint.sh"]

EXPOSE 2368
CMD ["npm", "start"]

【问题讨论】:

您可以删除ENTRYPOINT 并将两者都放入CMDCMD /entrypoint.sh && npm start 您好,我按照您说的做了,但是在 psql 检查成功后,似乎仍然无法在 CMD 上执行命令。所以图像是构建的,我的 docker-compose 执行等待它的脚本,它是成功的,所以我的容器可以启动但是它出错了。什么都没有发生 我认为等待它的脚本需要参数。试试/entrypoint.sh localhost npm start。抱歉,我现在无法测试,因为我没有 Linux 机器。 【参考方案1】:

让我们先搞清楚几件事。当您在 Dockerfile 中同时使用 ENTRYPOINTCMD 时,CMD 值将作为参数传递给 ENTRYPOINT。因此,您当前在文件中的内容转换为

/entrypoint.sh npm start

这在您启动容器时执行。在不知道 entrypoint.sh 发生了什么的情况下,很难说这会产生什么影响。

码头工人

您可以进行以下更改,请尝试一下:

Dockerfile 中删除ENTRYPOINT

CMD 更改为以下内容:

CMD /wait-for-it.sh localhost && /entrypoint.sh npm start

这样做时,请调整以下内容:

wait-for-it.sh 的路径 - 请调整到您在 Dockerfile 中复制脚本文件的位置。我建议你将它复制到与entrypoint.sh相同的文件夹中。 wait-for-it.sh 脚本文件的 localhost 参数,请替换为您的数据库主机。

上面的内容是运行wait-for-it.sh 脚本,然后,一旦数据库启动,它就会运行您在ENTRYPOINTCMD 中的上一个命令。它应该与您目前拥有的相当。

作为替代方案,您也可以从您的 entrypoint.sh 脚本调用 wait-for-it.sh 脚本并仅运行附加步骤(一旦等待脚本成功,npm start)。由你决定...

Docker 编写

如果您使用 Docker-Compose 启动容器,您可以使用 docker-compose.yaml 文件中的 command 属性覆盖容器启动时执行的命令,例如

command: >
  bash -c "

  /wait-for-it.sh localhost 
  && /entrypoint.sh npm start
  "

请注意使用

bash -c 使用您选择的 shell(在本例中为 Bash)启动多个命令 引号,您需要它们才能有多行。

使用这种方法,您基本上可以将多个命令串联起来以依次运行,使用&& 运算符将它们组合起来。

等待脚本

顺便说一句:我将这个wait-for-it script 用于类似的目的,并以与上述相同的方式获得良好的结果。它比您的等待脚本版本更强大,并且几乎支持任何主机/端口组合。我用它来等待 MySQL - 你的问题不清楚是关于 MySQL 还是 PostgreSQL。

【讨论】:

感谢您的回复。我正在使用 mysql,但脚本是从 docker 文档中复制的,但适用于 mysql 并且运行良好。我也尝试使用 docker-compose 启动它,所以我还需要编辑 dockerfile 吗? 我已经用关于 Docker-Compose 的部分更新了答案

以上是关于成功等待脚本后如何启动 docker 容器的主要内容,如果未能解决你的问题,请参考以下文章

如何避免Docker容器启动脚本运行后自动退出

Docke及Docker Compose于微服务的实践

如何避免Docker容器启动脚本运行后自动退出

Docker容器启动后如何自动运行脚本

如何在不同的(依赖的)容器启动后对 docker 容器运行 .sql 脚本?

简单使用docker