首页  

Dockerfile 中 CMD 和 ENTRYPOINT 区别     所属分类 docker 浏览量 4
一. 核心区别 
ENTRYPOINT:
容器启动时 必须执行的命令 / 程序,优先执行
不可被覆盖(用 --entrypoint 才能覆盖),适合定义容器主进程。

CMD:
默认参数 / 默认命令,可以被覆盖,
适合给 ENTRYPOINT 传参,或单独写默认启动命令。

二. 几种使用方式 
1. 单独用 CMD(最简单)

CMD ["echo", "Hello Docker"]

运行:docker run 镜像 → 输出 Hello Docker
覆盖:docker run 镜像 echo Hi → 输出 Hi(CMD 被直接替换)
适合:简单容器、测试、临时命令。

2. 单独用 ENTRYPOINT(固定命令)

ENTRYPOINT ["echo", "Hello"]

运行:docker run 镜像 → Hello
运行:docker run 镜像 Docker → Hello Docker(后面内容变成参数)
想覆盖必须:docker run --entrypoint ls 镜像
适合:必须固定启动的主程序(Nginx、Java、Python 服务)

3. ENTRYPOINT + CMD(最标准、最推荐)

ENTRYPOINT ["echo"]   # 固定主命令
CMD ["Hello Docker"]  # 默认参数

直接运行:docker run 镜像 → echo Hello Docker
传参运行:docker run 镜像 Hi → echo Hi(CMD 被替换)
CMD 被 docker run 命令直接覆盖 !!!
生产环境标准写法:固定主程序 + 灵活传参。



三. exec 格式 vs shell 格式

1. exec 格式(推荐 )

ENTRYPOINT ["nginx", "-g", "daemon off;"]
CMD ["python", "app.py"]

不会启动额外 shell
信号能传递(docker stop 能正常停止容器)
必须双引号 + JSON 数组格式



ENTRYPOINT ["java","-jar","app.jar"]
CMD ["--env","prod"]

直接创建进程作为 PID 1
能接收 docker stop 信号,优雅停机
不经过 /bin/sh -c,无 shell ,环境变量自动解析



2. shell 格式(不推荐 )


ENTRYPOINT nginx -g "daemon off;"
CMD python app.py

会用 /bin/sh -c 执行
无法接收信号,容器可能无法优雅关闭



ENTRYPOINT java -jar app.jar

实际等价:/bin/sh -c "java -jar app.jar"
PID 1 是 sh,业务进程是子进程
docker stop 收不到信号,容易杀不掉容器、僵尸进程
生产禁止用 Shell 模式


四. 其他 

强制覆盖 ENTRYPOINT?
docker run --entrypoint 或 docker-compose 里 entrypoint 字段。

临时覆盖入口程序
docker run --entrypoint /bin/sh 镜像名

混用 Shell 和 Exec 格式ENTRYPOINT 数组、CMD 写字符串,参数拼接错乱。

PID 1 不是业务进程Shell 模式导致,容器无法正常 stop,只能 kill -9。

一个 Dockerfile 只能最后一条 ENTRYPOINT / CMD 生效,前面的会被覆盖

优先级:
ENTRYPOINT + CMD > 单独 ENTRYPOINT > 单独 CMD


ENTRYPOINT ["java","-jar","app.jar"]
CMD ["--spring.profiles.active=dev"]
docker run 镜像 --spring.profiles.active=prod
自动替换 CMD 部分,变成:
java -jar app.jar --spring.profiles.active=prod

上一篇    
docker compose up 和 restart 的区别

2026年了 docker还流行吗

docker inspect 查看 镜像/容器 信息