具有入口点变量展开和CMD参数的Docker容器

具有入口点变量展开和CMD参数的Docker容器,docker,dockerfile,docker-container,docker-image,Docker,Dockerfile,Docker Container,Docker Image,我想创建一个Docker映像,作为可执行文件,用户将令牌作为环境变量传递给它。可执行文件有用户应该通过dockers CMD传递的子命令(想想git,它通过Env进行身份验证)。 但是,Docker不会将CMD附加到入口点。 我的Dockerfile的相关部分如下所示: ENTRYPOINT ["/bin/sh", "-c", "/usr/bin/mycmd --token=$MY_TOKEN"] CMD ["pull", "stuff"] 因此,如果这个容器在执行时没有任何CMD覆盖,并且s

我想创建一个Docker映像,作为可执行文件,用户将令牌作为环境变量传递给它。可执行文件有用户应该通过dockers CMD传递的子命令(想想git,它通过Env进行身份验证)。 但是,Docker不会将CMD附加到入口点。 我的Dockerfile的相关部分如下所示:

ENTRYPOINT ["/bin/sh", "-c", "/usr/bin/mycmd --token=$MY_TOKEN"]
CMD ["pull", "stuff"]
因此,如果这个容器在执行时没有任何CMD覆盖,并且
secret
作为MY_TOKEN变量,我希望

mycmd --token=secret pull stuff
待执行。如果用户使用覆盖启动容器,例如

docker run -it -e MY_TOKEN=secret myimage push junk
我希望

mycmd --token=secret push junk
待执行。但是,如上所述,只有
mycmd--token=secret
被执行,CMD被忽略-无论我是在启动时重写它还是在Dockerfile中设置它。

按照指定,您指定的是调用shell的入口点(因此不是shell形式,而是exec形式)。参数被传递到shell(因此被忽略);只有shell中的命令才重要。将entrypoint调用切换到以下位置后,您将看到问题得到解决:

ENTRYPOINT[“usr/bin/mycmd”,“--token=$myu token”]

在入口点中调用shell是非常不受欢迎的,并且只有在您希望避免图像用户将自定义参数附加到入口点时才有用

网上见!:)

使用
/bin/sh-c“script”
语法,
-c
参数之后的任何内容都将成为脚本的参数。作为/bin/sh脚本的一部分,您可以使用
$0
$@
访问它们:

ENTRYPOINT ["/bin/sh", "-c", "exec /usr/bin/mycmd --token=$MY_TOKEN $0 $@"]
CMD ["pull", "stuff"]
请注意,您还可以将入口点更改为添加到映像中的shell脚本,该脚本运行
exec/usr/bin/mycmd--token=$MY_token“$@”
,并使用docker的exec语法执行该shell脚本:

ENTRYPOINT ["/entrypoint.sh"]

您是否尝试过docker run-it-e MY_TOKEN=secret myimage“推送垃圾”?是的,这也不起作用。这也不能解释为什么在docker Run中不重写CMD时,
就不能工作。请尝试使用
CMD[“sh”、“-c”、“pull”、“stuff”]
更改docker文件中的CMD,重新创建一个图像,然后重新尝试将整个入口点移动到另一个shell脚本中。可能CMD被传递到/bin/sh而不是/usr/bin/mycmd。ENTRYPOINT[“/bin/sh”,“/ENTRYPOINT.sh”]您是否考虑过这一点:这不起作用,因为在exec表单中,没有扩展环境变量:
docker:Error-response-from-daemon:oci-runtime-Error:container\u-linux.go:247:启动容器进程导致“exec:\”/usr/bin/mycmd--token=$MY\u-token\“:stat/usr/bin/mycmd--token=$MY_token:没有这样的文件或目录”。
正确的方法是:
ENTRYPOINT[“usr/bin/mycmd”,“--token=$MY_token”]
这与David的回答中的行相同。同样,这不会扩展环境变量,因为它使用exec表单。抱歉,我读错了。这实际上实现了正确的子命令替换。但是,缺少环境变量扩展的问题仍然存在。我不确定问题是否真的缺少env substit注意。答案中指定的方式使docker试图将字符串“usr/bin/mycmd--token=$MY_token”定位为二进制,并因此抱怨“没有这样的文件或目录”。Ricardo的注释显示了正确的语法。我已将命令更新为使用“exec”“在/usr/bin/mycmd之前删除作为pid 1.+1运行的额外shell脚本,以使用
/entrypoint.sh
和exec。需要注意的是:您应该引用
$@
,例如:
exec/usr/bin/mycmd--token=$MY_token“$@
。否则,当参数中遇到空格时,可能会出现奇怪的行为。