【问题标题】:Dockerfile Entrypoint seems to append instead of overwriteDockerfile 入口点似乎是追加而不是覆盖
【发布时间】:2023-03-13 16:13:01
【问题描述】:

我想覆盖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


    【解决方案1】:

    要覆盖 ENTRYPOINT,您应该使用 --entrypoint 选项。在镜像名称之后传递的任何参数都将是 Dockerfile 中指定为 ENTRYPOINT 的现有命令的参数(覆盖 CMD)。

    【讨论】:

    • 谢谢,它有效。但我也想覆盖 dockerfile 中的入口点,因为我不想将入口点暴露给运行容器的用户。
    【解决方案2】:

    请记住,ENTRYPOINTCMDRUN 有两种形式。您可以将这些命令“拼写”成裸字符串或 JSON 数组。如果您使用裸字符串,Docker 会隐式包装您在 /bin/sh -c '...' 中放置的任何内容。

    Dockerfile 文档中有一个表格描述了Understand how CMD and ENTRYPOINT interact。根据该表,如果ENTRYPOINT 是裸字符串,则始终忽略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"]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-23
      • 1970-01-01
      • 2016-06-19
      • 2012-07-13
      • 1970-01-01
      • 2017-09-19
      • 2022-01-01
      相关资源
      最近更新 更多