entrypoint 用于精确控制容器启动命令,默认参数由 cmd 提供;推荐使用 exec 格式(如 ["cmd","arg"])以支持参数透传和信号处理,避免 shell 格式导致的 pid 和信号问题。

通过 Dockerfile 中的 ENTRYPOINT 指令,你可以精确控制容器启动时执行的命令及其默认参数,这是构建可复用、易维护镜像的关键机制之一。它和 CMD 协同工作,但语义更明确:前者定义“执行什么”,后者定义“传什么参数”。掌握好 ENTRYPOINT 的两种写法(shell 和 exec 形式)及与 CMD 的配合逻辑,能避免常见启动失败或参数被忽略的问题。
理解 ENTRYPOINT 的两种格式
ENTRYPOINT 支持 shell 格式和 exec 格式,二者行为差异显著:
-
Shell 格式:
ENTRYPOINT command param1 param2—— 实际以/bin/sh -c "command param1 param2"方式运行,无法接收docker run后追加的参数,且 PID 为 shell 进程(非主程序),不利于信号传递和优雅退出。 -
Exec 格式:
ENTRYPOINT ["command", "param1", "param2"]—— 直接执行指定程序,PID 为该进程本身,支持接收docker run后的参数,并能正确响应SIGTERM等信号。
推荐始终使用 exec 格式,尤其在生产环境中。
ENTRYPOINT + CMD 的协作逻辑
当两者同时存在时,CMD 提供的是 ENTRYPOINT 的默认参数(仅在 exec 格式下生效)。例如:
ENTRYPOINT ["nginx", "-g"] CMD ["daemon off;"]
等价于运行 nginx -g "daemon off;";若运行 docker run my-nginx -c /etc/nginx/nginx.conf,则最终执行的是 nginx -g -c /etc/nginx/nginx.conf(CMD 被完全替换)。
常见误区是误以为 CMD 可追加参数——实际它只作为默认值,在 docker run 指定命令时会被整体覆盖。
编写可扩展的入口脚本(推荐进阶用法)
对复杂初始化场景(如环境变量注入、配置生成、健康检查前置),建议将 ENTRYPOINT 指向一个 shell 脚本(仍用 exec 格式调用):
- 在
Dockerfile中写:ENTRYPOINT ["./docker-entrypoint.sh"] - 脚本开头需有
#!/bin/sh,并设可执行权限(RUN chmod +x docker-entrypoint.sh) - 脚本末尾通常用
exec "$@"将剩余参数透传给主程序,保持兼容性。例如:
#!/bin/sh echo "Running pre-start tasks..." # 生成配置、等待依赖等... exec "$@"
这样既保留了初始化能力,又不破坏用户自定义命令的能力。
调试与验证技巧
启动失败时,快速定位 ENTRYPOINT 问题的方法:
- 用
docker run --rm -it <image> sh</image>跳过入口点,进入容器手动测试命令路径和权限 - 查看镜像元数据:
docker inspect <image> | jq '.[0].Config.Entrypoint, .[0].Config.Cmd'</image> - 临时覆盖入口点调试:
docker run --entrypoint sh <image> -c 'echo $0; ps aux'</image>
确保脚本中所有依赖命令(如 jq、curl)已预装,避免因基础镜像精简导致运行时报 “command not found”。











