«

**`docker-compose.yml` 中的 `command` 字段会完全覆盖 Dockerfile 中的 `CMD`(甚至可以覆盖 `ENTRYPOINT` 的参数),并且不会追加,是“替换”行为。**

时间:2025-8-12 15:26     作者:wanzi     分类:


✅ 结论先行:

docker-compose.yml 中的 command 字段会完全覆盖 Dockerfile 中的 CMD(甚至可以覆盖 ENTRYPOINT 的参数),并且不会追加,是“替换”行为。


🔍 详细解释

我们从 Docker 的执行机制说起:

Docker 启动命令优先级(从高到低):

优先级 来源 说明
1️⃣ 最高 docker rundocker-compose command 直接指定命令,完全覆盖 CMDENTRYPOINT 参数
2️⃣ 中 CMD(Dockerfile) 默认命令,可被覆盖
3️⃣ 低 ENTRYPOINT(Dockerfile) 基础命令,通常不可变,CMD 作为其参数

✅ 示例说明

场景 1:Dockerfile 中有 CMD

# Dockerfile
FROM ubuntu:20.04
CMD ["echo", "Hello World"]
# docker-compose.yml
version: '3'
services:
  app:
    build: .
    command: echo "Custom Message"

✅ 实际执行:echo "Custom Message"
CMD 被完全替换,不会执行原命令


场景 2:ENTRYPOINT + CMDcommand 覆盖

FROM nginx:alpine
ENTRYPOINT ["/usr/sbin/nginx"]
CMD ["-g", "daemon off;"]
# docker-compose.yml
version: '3'
services:
  web:
    image: nginx:alpine
    command: ["-g", "daemon off;", "-s", "reload"]

✅ 实际执行:/usr/sbin/nginx -g "daemon off;" -s reload
👉 command 提供的参数会作为 ENTRYPOINT 的新参数,替换原来的 CMD

⚠️ 注意:这里 command 并没有替换 ENTRYPOINT 本身,而是替换了它接收的参数(即原 CMD 的内容)


场景 3:command 完全自定义(跳过 ENTRYPOINT 参数机制)

command: ["sh", "-c", "echo 'hello' && sleep 10"]

✅ 这会完全绕过原来的 ENTRYPOINTCMD,直接执行新命令
👉 相当于:docker run ... sh -c "echo 'hello' && sleep 10"


✅ 总结:command 的行为

情况 command 的作用
Dockerfile 有 CMD ✅ 完全替换 CMD
Dockerfile 有 ENTRYPOINT + CMD ✅ 替换 CMD 部分,作为 ENTRYPOINT 的新参数
command 写成 ["sh", "-c", "..."] ✅ 完全绕过 ENTRYPOINTCMD,执行全新命令
command 为空数组 ✅ 使用镜像默认的 CMD

🆚 command vs entrypoint in docker-compose

字段 作用
command 替换 CMD,或作为 ENTRYPOINT 的参数
entrypoint 替换 Dockerfile 中的 ENTRYPOINT

示例:完全自定义入口

services:
  app:
    image: myapp
    entrypoint: ["/bin/bash"]
    command: ["-c", "echo start && ./run.sh"]

👉 相当于:/bin/bash -c "echo start && ./run.sh"


✅ 如何验证?

docker-compose run app ps aux
# 或查看实际启动命令
docker inspect <container_id> | grep -A 10 "Cmd\|Entrypoint"

✅ 最佳实践建议


✅ 所以你总结得非常准确:

docker-compose 中的 command 会完全替换 CMD,不是追加,是覆盖。

这是 Docker 的标准行为,也是设计如此。