首页 > 解决方案 > Dockerfile 入口点似乎是追加而不是覆盖

问题描述

我想覆盖dockerfile中的入口点,但结果显示最终入口点是基础映像的入口点附加我的入口点。这是我的 Docker 文件。

FROM ubuntu:18.04
ENTRYPOINT echo 1
CMD 2

通过构建此映像后docker build -t test . ,我通过运行容器docker run test 3

我想,最后执行的命令是echo 1 2 3,结果应该是1 2 3

但是,结果是“1”。

我使用查询实际命令docker inspect -f "{{.Name}} {{.Path}} {{.Args}}" $(docker ps -a -q),得到以下结果。 /adoring_chaum /bin/sh [-c echo 1 2]

看起来实际的命令是旧的入口点,新的入口点作为参数。并且dockerfile和运行时参数中的CMD被忽略了。

我无法从 docker 文档中找到任何解释。

谁能给我一个解释?

标签: docker

解决方案


ENTRYPOINT请记住,CMD和有两种形式RUN。您可以将这些命令“拼写”成裸字符串或 JSON 数组。如果您使用裸字符串,Docker 会隐式包装您在/bin/sh -c '...'.

Dockerfile 文档中有一个表格描述了理解 CMD 和 ENTRYPOINT 如何交互。根据该表, ifENTRYPOINT是一个裸字符串,CMD总是被忽略。

(这在技术上不是 100% 准确,但更准确的答案取决于了解sh -c实际工作原理的神秘细节。)

如果您改用 JSON 数组形式,这将做您想做的事,以避免隐式sh -c包装

ENTRYPOINT ["/bin/echo", "1"]
CMD ["2"]

我通常认为有用的模式是为ENTRYPOINT执行一些首次设置的包装脚本保留,然后exec "$@"运行CMD​​. 一个典型的docker run命令有太多的参数,以至于能够为一个打包在 Docker 中的交互式工具省略命令词并没有太大的好处。如果您更喜欢独占CMD,那么运行调试 shell 会容易得多,如果您使用包装器,可能会在您首次设置时完成ENTRYPOINT

CMD ["/bin/echo", "1", "2"]

推荐阅读