docker - 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 文档中找到任何解释。
谁能给我一个解释?
解决方案
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"]
推荐阅读
- linux - 为什么 awk 模式匹配不返回结果?
- ruby-on-rails - 接口#index 中的 ActionController::UrlGenerationError
- javascript - 如何为每个用户存储一个号码
- python - 如何在张量流中提取图像精确坐标的向量?
- python - Python中Tkinter中的滚动条仅在悬停时有效
- java-websocket - Tomcat 9 上的 Java Web Socket - 一些问题
- delphi - 如何同时拥有 Tooltip 和 Hint 提示模式?
- html - 我需要将右侧的 2 行(2018 年和 2017 年)分开,以便有一些空格。有很多麻烦
- javascript - 重定向到 Page.aspx 重定向到未定义
- azure - 如何使我的仪表板小部件呈现为条形图而不是表格 - Azure 仪表板