Shell 重用继承的映像';s CMD或入口点

Shell 重用继承的映像';s CMD或入口点,shell,docker,dockerfile,Shell,Docker,Dockerfile,如何在容器启动/重新启动/附加时包含自己的shell脚本CMD,而不删除继承映像使用的CMD 我正在使用它,它确实可以很好地执行我的脚本,但似乎覆盖了PHPCMD: FROM php COPY start.sh /usr/local/bin CMD ["/usr/local/bin/start.sh"] 我应该怎么做?我正在避免复制/粘贴父映像的入口点或CMD,这可能不是一个好方法。如果基础映像不是您的,很遗憾,您必须手动调用父命令 如果您拥有父映像,您可以尝试camptocamp的人员建

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

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

FROM php

COPY start.sh /usr/local/bin

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

我应该怎么做?我正在避免复制/粘贴父映像的入口点或CMD,这可能不是一个好方法。

如果基础映像不是您的,很遗憾,您必须手动调用父命令

如果您拥有父映像,您可以尝试
camptocamp
的人员建议的内容

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

然而,这意味着您必须通过在脚本前面加前缀来维持顺序,这可能会失控。(假设父映像决定稍后添加新脚本…)

不管怎样,那可能行得通

更新#1 关于容器运行后的资源调配,有很多讨论。一个建议是将docker run或compose命令包装在shell脚本中,然后在其他命令上运行docker exec


如果您想使用这种方法,基本上可以将父CMD作为run命令,并在docker运行后将您的命令作为docker exec放置。

如注释中所述,没有内置的解决方案。在Dockerfile中,您看不到当前
CMD
入口点的值。如果您控制上游基本映像并在其中包含此代码,从而允许下游组件进行更改,那么拥有一个
运行部件
解决方案是很好的。但是docker有一个固有的问题会导致这个问题,容器应该只运行一个需要在前台运行的命令。因此,如果上游映像启动,它将保持运行,而不会给后面的步骤提供运行的机会,因此您将面临确定运行命令顺序的复杂性,以确保单个命令最终在不退出的情况下运行

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

#!/bin/sh

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

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

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

运行容器时,您希望发生什么?Docker无论如何只运行一个
CMD
。@jwodder我想在
php
image.Right设置的
CMD
末尾“附加”我自己的
CMD
。这基本上就是问题所在。有哪些docker方法可以实现这一点?@Cyclonecode您知道如何访问父映像的入口点或CMD吗?需要注意的是,如果您继承的映像同时定义了
ENTRYPOINT
CMD
,则可能需要定义参数,以便执行
exec
命令工作我曾经遇到过这样的情况:上游入口点至少需要一个参数,否则它将终止而没有错误和输出。我仍然感到惊讶的是,在Dockerfile中扩展父映像时,没有内置选项或简单的方法来捕获父映像的CMD。我没有接受这个答案,因为我认为肯定会有一个功能或一个很好的方法来解决这个问题,但两年后我感觉我仍然误解了一些核心概念。在这篇评论中,在子Dockerfile中指定ENTRYPOINT将消除父级的CMD。您需要在您的入口点后指定父级的CMD。@JonShipman这是一个已知和预期的行为:我需要在我的断臂链接(camptocamp)中纹身此命令感谢@danfromisrael,我已经更新了链接