github编辑

CMD 容器启动命令

什么是 CMD

CMD 指令用于指定容器启动时默认执行的命令。它定义了容器的"主进程"。

核心概念:容器的生命周期 = 主进程的生命周期。CMD 指定的命令就是这个主进程。


语法格式

CMD 有三种格式:

格式
语法
推荐程度

exec 格式

CMD ["可执行文件", "参数1", "参数2"]

推荐

shell 格式

CMD 命令 参数1 参数2

⚠️ 简单场景

参数格式

CMD ["参数1", "参数2"]

配合 ENTRYPOINT

exec 格式(推荐)

CMD ["nginx", "-g", "daemon off;"]
CMD ["python", "app.py"]
CMD ["node", "server.js"]

优点

  • 直接执行指定程序,是容器的 PID 1

  • 正确接收信号(如 SIGTERM)

  • 无需 shell 解析

shell 格式

实际执行:会被包装为 sh -c

优点:可以使用环境变量、管道等 shell 特性 缺点:主进程是 sh,信号无法正确传递给应用


exec 格式 vs shell 格式

特性
exec 格式
shell 格式

主进程

指定的程序

/bin/sh

信号传递

✅ 正确

❌ 无法传递

环境变量

❌ 需要 shell 包装

✅ 自动解析

推荐使用

✅ 大多数场景

需要 shell 特性时

信号传递问题示例


运行时覆盖 CMD

docker run 后的命令会覆盖 Dockerfile 中的 CMD:


经典错误:容器立即退出

错误示例

原因分析

正确做法


CMD vs ENTRYPOINT

指令
用途
运行时行为

CMD

默认命令

docker run 参数会覆盖

ENTRYPOINT

入口点

docker run 参数会追加到它后面

单独使用 CMD

搭配 ENTRYPOINT

详见 ENTRYPOINT 入口点 章节。


最佳实践

1. 优先使用 exec 格式

2. 确保应用在前台运行

3. 使用双引号

4. 配合 ENTRYPOINT 使用


常见问题

Q: CMD 可以写多个吗?

不可以。多个 CMD 只有最后一个生效:

Q: 如何在 CMD 中使用环境变量?

Q: 为什么我的容器不响应 Ctrl+C?

可能是使用了 shell 格式,信号被 sh 吃掉了:


本章小结

要点
说明

作用

指定容器启动时的默认命令

推荐格式

exec 格式 CMD ["程序", "参数"]

覆盖方式

docker run image 新命令

与 ENTRYPOINT

CMD 作为 ENTRYPOINT 的默认参数

核心原则

应用必须在前台运行

延伸阅读

最后更新于