ENTRYPOINT 固定容器启动入口,使镜像封装稳定运行环境,CMD 提供默认参数并可被运行时覆盖;推荐 exec 形式以确保 PID 1 正确接收信号,entrypoint.sh 可封装初始化逻辑,末行须用 exec "$@" 实现信号透传与控制权移交。

ENTRYPOINT 让容器启动命令与镜像职责分离,是实现“镜像即程序”和启动逻辑复用的关键机制。
ENTRYPOINT 的核心作用:固定执行入口
Dockerfile 中的 ENTRYPOINT 指定容器启动时**始终执行的命令或脚本**,它不会被 docker run 命令行参数覆盖(不像 CMD),而是把 run 后的参数作为它的参数传递进去。这使得镜像可以封装稳定的基础运行环境,而具体行为由运行时决定。
- 使用 exec 形式(推荐):ENTRYPOINT ["./entrypoint.sh"] —— 直接执行脚本,PID 1 是脚本本身,能正确接收信号
- 避免 shell 形式:ENTRYPOINT ./entrypoint.sh —— 会启动 /bin/sh -c 包裹,导致 PID 1 不是脚本,可能无法响应 SIGTERM
与 CMD 协同:默认参数 + 运行时覆盖
ENTRYPOINT 定义“做什么”,CMD 提供“怎么做”的默认参数。二者配合,既保证基础行为不变,又保留灵活性。
- 示例:
ENTRYPOINT ["python", "app.py"]
CMD ["--host", "0.0.0.0:8000"]
→ 默认运行 python app.py --host 0.0.0.0:8000
→ 运行时执行 docker run myimg --debug → 实际执行 python app.py --debug - 关键点:CMD 内容整体作为 ENTRYPOINT 的参数追加,不是替换整个命令
用 entrypoint.sh 封装初始化逻辑
复杂应用常需检查配置、等待依赖就绪、生成配置文件等。把这些逻辑写进 entrypoint.sh,再设为 ENTRYPOINT,就能确保每次启动都经过统一预处理。
- 典型结构:
– 检查必要环境变量(如 DB_URL)
– 执行数据库迁移(如 alembic upgrade head)
– 等待 PostgreSQL 启动完成(用 nc -z 或 pg_isready)
– 最后用 exec "$@" 转交控制权给 CMD 或用户命令 - 注意:最后一行必须是 exec "$@"(不是 exec $@),否则信号无法透传,且会多一层 shell 进程
调试与验证技巧
确认 ENTRYPOINT 是否生效,不能只看 docker run 输出,要观察实际进程树和信号行为。
- 查看容器内 PID 1:docker exec -it
ps -p 1 —— 应显示 entrypoint.sh 或你指定的主进程 - 测试信号转发:docker stop
后检查应用是否优雅退出(如日志中出现 shutdown message) - 临时绕过 ENTRYPOINT 调试:docker run --entrypoint /bin/sh myimg -c "ls -l"

















