CMD
和 ENTRYPOINT
都用于在容器启动时指定执行的命令,但它们有不同的行为、用途和优先级。结合覆盖相关的内容,我们可以更清晰地总结它们的区别和使用方式。
1. 功能定位
指令 | 主要用途 |
---|---|
CMD | 为容器提供默认的命令或参数,可以被 docker run 提供的命令完全覆盖。 |
ENTRYPOINT | 定义容器的主进程,不会被 docker run 提供的命令覆盖,但可以通过 --entrypoint 显式替换。 |
2. 行为差异
CMD 的行为
- 默认命令:
CMD
是容器的默认命令,只有当运行容器时没有指定命令时,CMD
才会执行。 - 完全覆盖:如果在
docker run
后提供了命令,则CMD
的内容会被完全替代。
ENTRYPOINT 的行为
- 强制主进程:
ENTRYPOINT
会始终执行,即使运行时提供了命令,命令也会作为参数传递给ENTRYPOINT
,而不会替换它。 - 覆盖方式:可以使用
--entrypoint
参数显式覆盖ENTRYPOINT
。
3. 优先级规则
情景 | 运行的命令 |
---|---|
仅定义 CMD | 执行 CMD 的内容。 |
仅定义 ENTRYPOINT | 执行 ENTRYPOINT 的内容。 |
同时定义 ENTRYPOINT 和 CMD | ENTRYPOINT 执行,CMD 提供默认参数,运行时传入的命令会替代 CMD 参数而不是覆盖 ENTRYPOINT 。 |
使用 --entrypoint 覆盖 | 显式替换 ENTRYPOINT ,CMD 被忽略,运行时命令直接执行。 |
4. 示例对比
仅使用 CMD
dockerfile
FROM ubuntu:20.04
CMD ["echo", "Default CMD"]
- 运行容器时默认执行
CMD
:
输出:docker run <image>
Default CMD
- 运行时提供命令会覆盖
CMD
:
输出:docker run <image> echo "Override CMD"
Override CMD
仅使用 ENTRYPOINT
dockerfile
FROM ubuntu:20.04
ENTRYPOINT ["echo"]
- 运行容器时,
ENTRYPOINT
始终生效:
输出:docker run <image> Default
Default
- 即使提供命令,命令也只是作为参数传递给
ENTRYPOINT
:
输出:docker run <image> "Override EntryPoint"
Override EntryPoint
- 使用
--entrypoint
替换:
输出:docker run --entrypoint "/bin/bash" <image> -c "echo 'New EntryPoint'"
New EntryPoint
CMD + ENTRYPOINT 结合使用
dockerfile
FROM ubuntu:20.04
ENTRYPOINT ["echo"]
CMD ["Default CMD"]
- 默认情况下,
CMD
的内容作为参数传递给ENTRYPOINT
:
输出:docker run <image>
Default CMD
- 运行时提供的命令会替代
CMD
的内容(但不会替换ENTRYPOINT
):
输出:docker run <image> "Override CMD"
Override CMD
- 使用
--entrypoint
替换时,CMD
被忽略:
输出:docker run --entrypoint "/bin/bash" <image> -c "echo 'New EntryPoint'"
New EntryPoint
5. 使用场景
CMD 的适用场景
- 为镜像提供默认行为,但允许运行时完全覆盖。
- 例如:
CMD ["nginx", "-g", "daemon off;"]
- 默认运行 Nginx。
- 运行时可以完全替代默认命令,例如:
docker run <image> bash
ENTRYPOINT 的适用场景
- 确保容器始终运行指定的主进程,例如服务或脚本。
- 配合
CMD
提供默认参数。 - 例如:
dockerfile
ENTRYPOINT ["python3"] CMD ["app.py"]
- 默认运行
python3 app.py
。 - 运行时可以替代
app.py
:
输出:docker run <image> other_script.py
python3 other_script.py
- 默认运行
6. 总结区别
属性 | CMD | ENTRYPOINT |
---|---|---|
是否被覆盖 | 容器运行时命令会完全替代 CMD 的内容。 | 容器运行时命令作为参数传递,不替代 ENTRYPOINT 。 |
主进程定义 | 定义默认命令,但不是强制的主进程。 | 定义容器的主进程,容器生命周期依赖它。 |
配合使用的作用 | 为 ENTRYPOINT 提供默认参数。 | 始终执行主程序,CMD 或运行时命令提供参数。 |
覆盖方式 | 容器运行时直接指定新命令即可覆盖。 | 使用 --entrypoint 替代。 |
推荐
- 使用
CMD
设置可选的默认行为。 - 使用
ENTRYPOINT
定义强制的主程序,配合CMD
提供默认参数,确保容器行为更可控。