ENTRYPOINT 定义容器默认主命令,运行时参数追加其后;shell 格式忽略用户参数,exec 格式支持参数拼接;仅 --entrypoint 可覆盖,CMD 仅作 ENTRYPOINT 的默认参数。

Dockerfile 中的 ENTRYPOINT 指令设计为定义容器启动时**默认执行的主命令**,其核心特性是:当使用 docker run 命令显式传入参数时,这些参数会**作为参数追加到 ENTRYPOINT 命令之后**,而不会替换整个命令;只有通过 --entrypoint 选项才能真正覆盖它。
ENTRYPOINT 的两种写法影响覆盖行为
ENTRYPOINT 支持 shell 格式和 exec 格式,二者在参数传递和覆盖逻辑上有关键区别:
-
Shell 格式(
ENTRYPOINT command param1 param2):实际被包装在/bin/sh -c中执行,此时docker run后跟的参数会被忽略(因为 shell 形式不支持接收额外参数),除非你手动在镜像中处理$@—— 但这种写法本身就不利于参数覆盖,也不推荐用于需要灵活传参的场景。 -
Exec 格式(
ENTRYPOINT ["cmd", "param1", "param2"]):这是推荐写法。此时docker run myimage arg1 arg2会等价于执行cmd param1 param2 arg1 arg2。也就是说,镜像定义的 entrypoint 是“固定前缀”,用户参数是“可变后缀”。
覆盖 ENTRYPOINT 的唯一标准方式是 --entrypoint
若想完全替换掉 Dockerfile 中定义的 ENTRYPOINT,必须在运行时显式指定:
-
docker run --entrypoint /bin/sh myimage -c 'echo hello'→ 启动 /bin/sh 而非原 ENTRYPOINT -
docker run --entrypoint "" myimage ls /app→ 空字符串表示清空 ENTRYPOINT,此时 CMD 或传入参数直接作为命令执行 - 注意:
--entrypoint的值必须是可执行文件路径(如/bin/bash),不能是 shell 表达式;且它会完全取代原有 ENTRYPOINT,包括其所有预设参数。
CMD 与 ENTRYPOINT 协同工作的逻辑
CMD 在存在 ENTRYPOINT 时,**仅作为默认参数提供给 ENTRYPOINT 使用**,而非独立命令:
- 若 Dockerfile 中同时有
ENTRYPOINT ["nginx", "-g"]和CMD ["daemon off;"],则docker run mynginx等效于nginx -g "daemon off;" - 若运行时传参:
docker run mynginx "-e debug",则最终执行nginx -g "-e debug"(CMD 被忽略,用户参数直接补在 ENTRYPOINT 后) - 这意味着:CMD 是“默认参数”,ENTRYPOINT 是“默认命令”,二者组合才构成完整启动指令。
调试与验证 ENTRYPOINT 行为的方法
遇到 ENTRYPOINT 不按预期工作时,可通过以下方式快速定位:
- 用
docker inspect myimage查看Config.Entrypoint和Config.Cmd字段,确认实际生效值 - 临时覆盖为 sh 进入容器:
docker run --entrypoint /bin/sh -it myimage,检查文件结构或环境变量 - 避免混用 shell 和 exec 格式——例如不要在 ENTRYPOINT 用 shell 格式、又期望 CMD 参数被拼接,这会导致静默失效

















