CMD仅定义容器启动命令,不控制重启;重启由Docker重启策略(如no、on-failure、always、unless-stopped)决定,且每次重启都会重新执行CMD。

CMD 指令本身不决定容器是否重启,它只定义容器启动时默认执行的命令;容器是否重启,完全取决于 Docker 的重启策略(restart policy)设置。
CMD 是容器的“默认启动命令”,不是“守护进程”
CMD 在 docker run 未显式指定命令时生效,它会被覆盖。即使 CMD 启动的是一个前台进程(如 python app.py 或 nginx -g "daemon off;"),一旦该进程退出,容器就立即终止——CMD 不会自动重试、不监听崩溃、也不具备自愈能力。
- 例如:CMD ["sh", "-c", "echo hello && sleep 2"] 执行完就退出,容器停止
- 再如:CMD ["nginx"] 若 nginx 因配置错误启动失败,容器直接退出,不会重拉或重试
重启策略(restart policy)才是控制“容器死后是否复活”的开关
重启策略由 docker run --restart=xxx 或 docker-compose.yml 中的 restart: 字段指定,与 CMD 内容无关。常见策略包括:
- no:默认值,容器退出后不重启
- on-failure[:max-retries]:仅当容器以非零退出码终止时重启(适合 CMD 进程意外崩溃)
- always:无论退出码如何都重启(包括正常退出,慎用!可能造成无限重启循环)
- unless-stopped:始终重启,除非手动 docker stop(适合长期服务)
注意:重启是 Docker 守护进程发起的全新 exec,等价于再次运行 docker start,因此每次重启都会重新执行 CMD(或 ENTRYPOINT + CMD 组合)。
CMD 与 restart 策略协同工作的典型场景
真正起作用的是“CMD 提供可重复执行的稳定入口 + restart 策略提供兜底机制”:
- Web 服务:CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"] 配合 --restart=unless-stopped,进程挂了自动拉起
- 批处理任务:CMD ["bash", "-c", "do_work.sh && cleanup.sh"] 配合 --restart=no,执行完即停,无需重启
- 调试容器:CMD ["sleep", "3600"] 配合 --restart=on-failure,便于捕获异常退出但避免死循环
关键点:CMD 必须能被反复执行且行为一致;若 CMD 含有不可重入逻辑(如重复创建同名文件、绑定已被占用端口),配合 always 可能导致启动失败并陷入重启风暴。
不要混淆 CMD 和健康检查/存活探针
CMD 不参与容器健康状态判断。Docker 的健康检查(HEALTHCHECK)或 Kubernetes 的 livenessProbe 是独立机制,用于探测进程是否“活着”或“可用”。即使 CMD 进程仍在运行,若健康检查失败,上层编排系统(如 Swarm/K8s)可能主动 kill 并重建容器——这和 restart policy 触发的重启逻辑不同,但最终效果类似:旧容器终止,新实例启动并再次执行 CMD。

















