必须用 docker inspect 查看 Entrypoint 和 Cmd:若 Entrypoint 为 null 或 [],则 command 完全替代 CMD;若 Entrypoint 是数组(如 ["/app/entrypoint.sh"]),则 command 仅作其参数。

直接覆盖镜像默认入口命令,必须分清 ENTRYPOINT 和 CMD 的关系;只改 command 不碰 entrypoint,多数时候只是给入口脚本传参,不是真正“替换启动命令”。
怎么确认镜像用了 ENTRYPOINT 还是纯 CMD
运行 docker inspect 镜像名,重点看 Entrypoint 和 Cmd 两行输出:
- 如果
Entrypoint是null或[],说明没设入口点,此时command字段会完全替代镜像的CMD - 如果
Entrypoint是数组(如["/app/entrypoint.sh"]),那command的值会作为参数传给它执行,不是替换整个启动链 - 常见陷阱:以为改了
command就能绕过entrypoint.sh,结果发现日志里还是先跑了一遍初始化逻辑
docker-compose.yml 中写 command 的合法格式
错误写法比正确写法更容易导致容器静默退出或报错 executable file not found in $PATH:
- ✅ 推荐用数组:
command: ["nginx", "-g", "daemon off;"]—— 参数拆开,无 shell 解析歧义 - ✅ 简单场景可用字符串:
command: nginx -g "daemon off;"—— 注意这会被包装成sh -c "nginx -g \"daemon off;\"",引号嵌套容易翻车 - ❌ 别写成:
command: "nginx -g daemon off;"—— 整串当第一个参数传给sh,nginx找不到,报错sh: 1: nginx -g daemon off;: not found - ❌ 也别漏掉
exec:多命令要用sh -c包装,且开头加exec,否则 PID 1 不是你的主进程,信号收不到、无法优雅终止
想彻底绕过原 ENTRYPOINT?得同时清空 entrypoint
只设 command 不够,必须显式重置入口点:
- 在
docker-compose.yml里加这一行:entrypoint: [],再配command,才能真正从零定义启动流程 - 等价于命令行运行时加
--entrypoint="",比如:docker run --entrypoint="" -it redis redis-server --appendonly yes - 不这么做,哪怕
command写了完整命令,也会被原entrypoint.sh拦截、解析、甚至改写参数(比如自动加-D或环境变量)
Windows 上 Docker Desktop 的额外注意点
WSL2 后端下,路径、权限、换行符都可能干扰入口脚本执行:
- 自定义
entrypoint.sh文件若在 Windows 编辑器里保存,务必选 Unix 换行符(LF),否则/bin/sh^M: bad interpreter - 挂载进容器的脚本文件需有可执行权限:
chmod +x entrypoint.sh,Windows 默认没这个属性,得在 WSL2 里手动补 - 镜像若依赖
/dev/urandom或systemd,在 Desktop 环境下可能缺失或受限,这类入口行为在 Linux 主机上正常,但在 Desktop 容器里会卡住或崩溃
真正难的不是写对语法,而是判断「这个镜像到底靠什么启动」——有些镜像把逻辑全塞进 ENTRYPOINT,CMD 只是摆设;有些又反过来。每次换镜像,先 inspect 一眼,比硬试三次 command 更省时间。











