重用inheritance的图像的CMD或ENTRYPOINT

我怎样才能包括我自己的shell脚本CMD的容器启动/重新启动/附加,而不删除由inheritance的图像使用的CMD

我正在使用这个,它执行我的脚本很好,但似乎覆盖PHP的CMD

 FROM php COPY start.sh /usr/local/bin CMD ["/usr/local/bin/start.sh"] 

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

正如评论中所提到的,这里没有内置的解决scheme。 在Dockerfile中,您看不到当前CMDENTRYPOINT的值。 如果您控制上游基础映像并在其中包含此代码,则允许下游组件进行更改,那么拥有run-parts解决scheme是非常好的。 但是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传输到上游入口点,以便正确处理信号。 后面的"$@"通过任何命令行parameter passing。 你可以使用set来调整$@的值,如果你想在你自己的start.sh脚本中处理和提取一些参数的话。

如果基本映像不是你的,那么你不得不手动调用父命令。

如果你拥有父母的形象,你可以尝试camptocamp的人在camptocampbuild议。

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

但是,这意味着您必须通过添加可能无法控制的脚本前缀来维持秩序。 (想象一下,父图像决定稍后添加一个新的脚本…)。

无论如何,这可以工作。

更新#1

关于这个docker在容器运行之后有一个长期的讨论。 一个build议是将你的docker run或compose命令封装在shell脚本中,然后在其他命令上运行docker exec。

如果您想要使用这种方法,您基本上将父CMD作为运行命令,并在docker运行后将其作为docker exec。