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 入口点arrow-up-right 章节。


最佳实践

1. 优先使用 exec 格式

具体内容如下:

2. 确保应用在前台运行

具体内容如下:

3. 使用双引号

具体内容如下:

4. 配合 ENTRYPOINT 使用

具体内容如下:


常见问题

Q: CMD 可以写多个吗?

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

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

具体内容如下:

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

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


本章小结

要点
说明

作用

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

推荐格式

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

覆盖方式

docker run image 新命令

与 ENTRYPOINT

CMD 作为 ENTRYPOINT 的默认参数

核心原则

应用必须在前台运行

延伸阅读

最后更新于