重用继承的图像的CMD或ENTRYPOINT

时间:2017-02-16 17:24:34

标签: shell docker dockerfile

如何在容器启动/重启/附加时包含我自己的shell脚本CMD,而不删除继承图像使用的CMD

我正在使用它,它可以很好地执行我的脚本,但似乎覆盖了PHP CMD

FROM php

COPY start.sh /usr/local/bin

CMD ["/usr/local/bin/start.sh"]

我应该做些什么?我避免了复制/粘贴父图像的ENTRYPOINT或CMD的前景,也许这不是一个好方法。

3 个答案:

答案 0 :(得分:18)

正如评论中所提到的,没有内置的解决方案。在Dockerfile中,您无法看到当前CMDENTRYPOINT的值。如果您控制上游基本映像并在其中包含此代码,那么拥有run-parts解决方案就很不错,允许下游组件进行更改。但是docker存在一个会导致问题的固有问题,容器应该只运行一个需要在前台运行的命令。因此,如果上游图像启动,它将保持运行而不会让您的后续步骤有机会运行,因此您将面临复杂性,以确定运行命令的顺序,以确保单个命令最终在不退出的情况下运行。

我的个人偏好是一个更简单和硬编码的选项,添加我自己的命令或入口点,并使我的命令的最后一步到exec上游命令。您仍然需要手动识别要从上游Dockerfile调用的脚本名称。但现在在你的start.sh中,您将拥有:

#!/bin/sh

# run various pieces of initialization code here
# ...

# kick off the upstream command:
exec /upstream-entrypoint.sh "$@"

通过使用exec调用,您可以将pid 1传输到上游入口点,以便正确处理信号。尾随"$@"遍历任何命令行参数。如果您要在自己的set脚本中处理和提取某些参数,则可以使用$@来调整start.sh的值。

答案 1 :(得分:4)

如果基本图像不是你的,你不幸的是必须手动调用父命令。

如果您拥有父图片,则可以尝试camptocamp的人here建议的内容。

他们基本上使用通用脚本作为在目录上调用run-parts的入口点。这样做是按字典顺序运行该目录中的所有脚本。因此,当您扩展图像时,只需将新脚本放在同一文件夹中即可。

但是,这意味着您必须通过为脚本添加前缀来维护顺序,这些脚本可能会失控。 (想象一下,父图像决定稍后添加一个新脚本......)。

无论如何,这可行。

更新#1

关于容器运行后的配置,this docker compose issue进行了长时间的讨论。一个建议是在shell脚本中包装docker run或compose命令,然后在其他命令上运行docker exec。

如果你想使用这种方法,你基本上将父CMD保留为运行命令,并在你的docker运行后将它们作为docker exec放置。

答案 2 :(得分:1)

以mysql镜像为例

执行 docker inspect mysql/mysql-server:5.7 并查看:

  • Config.Cmd="mysqld"
  • Config.Entrypoint="/entrypoint.sh"

我们放入 bootstrap.sh(记住 chmod a+x):

#!/bin/bash

echo $HOSTNAME
echo "Start my initialization script..."

# docker inspect results used here
/entrypoint.sh mysqld

Dockerfile 现在是:

FROM mysql/mysql-server:5.7
# put our script inside the image
ADD bootstrap.sh /etc/bootstrap.sh
# set to run our script
ENTRYPOINT ["/bin/sh","-c"]
CMD ["/etc/bootstrap.sh"]

构建并运行我们的新镜像:

  • docker build --rm -t sidazhou/tmp-mysql:5.7 .
  • docker run -it --rm sidazhou/tmp-mysql:5.7

输出:

6f5be7c6d587
Start my initialization script...
[Entrypoint] MySQL Docker Image 5.7.28-1.1.13
[Entrypoint] No password option specified for new database.
...
...

您会看到这与原始图像具有相同的输出:

docker run -it --rm mysql/mysql-server:5.7

[Entrypoint] MySQL Docker Image 5.7.28-1.1.13
[Entrypoint] No password option specified for new database.
...
...