CMD 和 ENTRYPOINT 共同决定容器启动命令:CMD 定义可覆盖的默认命令,ENTRYPOINT 固定主程序并使 CMD 变为其参数;推荐组合使用,配合 WORKDIR 和启动脚本提升健壮性。

设置容器启动时的默认执行命令,核心是用好 CMD 和 ENTRYPOINT 这两个 Dockerfile 指令。它们不是“可有可无”的配置项,而是决定容器一启动就跑什么的关键开关。
CMD:定义可被覆盖的默认命令
CMD 是最常用、也最灵活的方式,适用于大多数服务型镜像。它指定容器启动时默认执行的命令,但允许在 docker run 时用新命令覆盖。
- 语法推荐使用 JSON 数组格式(exec 形式),避免 shell 解析歧义:
CMD ["nginx", "-g", "daemon off;"] - 如果只写字符串形式(shell 形式),如
CMD nginx -g "daemon off;",Docker 会自动包装成/bin/sh -c执行,可能导致 PID 1 不是预期进程 - 一个 Dockerfile 中只能有一个 CMD 生效(后写的覆盖前面的)
- 没写 ENTRYPOINT 时,CMD 就是最终执行的命令;写了 ENTRYPOINT 后,CMD 变成它的默认参数
ENTRYPOINT:固定主程序,适合封装工具类镜像
ENTRYPOINT 更“强硬”,它把某个程序设为容器的“入口”,让容器行为更像一个可执行命令。CMD 在这时只起传参作用。
- 例如:
ENTRYPOINT ["python3", "/app/main.py"]+CMD ["--port", "8000"],默认运行python3 /app/main.py --port 8000 - 运行时加参数:
docker run my-app --port 9000 --debug,会替换掉 CMD 的全部内容,变成python3 /app/main.py --port 9000 --debug - 想临时绕过入口?用
--entrypoint覆盖:docker run --entrypoint /bin/bash my-app直接进 shell
组合使用:兼顾灵活性与确定性
生产中推荐 ENTRYPOINT + CMD 组合,既保证主程序不被误改,又保留参数定制空间。
- 工具镜像(如 curl、jq、migrate)适合纯 ENTRYPOINT:
ENTRYPOINT ["curl"],然后docker run my-curl https://api.example.com - 服务镜像(如 Nginx、Redis)通常用 ENTRYPOINT 调用包装脚本:
ENTRYPOINT ["docker-entrypoint.sh"],再由脚本处理初始化逻辑和最终调用 CMD - 调试阶段可临时禁用 ENTRYPOINT,用
--entrypoint /bin/sh进入容器排查问题
别忘了 WORKDIR 和启动脚本支持
默认命令往往依赖环境,比如工作目录或初始化逻辑。
- 用
WORKDIR /app明确容器启动后的当前路径,避免路径错误导致 CMD 失败 - 复杂启动流程建议写成脚本(如
startup.sh),再通过 CMD 或 ENTRYPOINT 调用:CMD ["/bin/bash", "/app/startup.sh"] - 脚本开头务必加
#!/bin/bash,并确保有执行权限(构建时用RUN chmod +x /app/startup.sh)


















