ENTRYPOINT 指令是什么
ENTRYPOINT 把镜像固定为某个可执行入口:docker run 的尾部命令不再替换它,而是作为参数追加。典型用法是「ENTRYPOINT 定入口加 CMD 给默认参数」,让镜像既能开箱运行又能被覆盖参数。写脚本型入口时必须用 exec 形式,并在脚本末尾用 exec "$@" 把参数转交出去,否则应用不是 PID 1,收不到停止信号。
基本信息
| 作用 | 固定入口,run 的尾部命令作为参数传给它 |
|---|---|
| 推荐形式 | ENTRYPOINT ["可执行", "参数"],即 exec 数组形式 |
| 与 CMD 组合 | ENTRYPOINT 定入口、CMD 给默认参数 |
| 临时覆盖 | docker run --entrypoint /bin/sh -it 镜像,用于调试 |
| 脚本要求 | 入口脚本末尾必须 exec "$@",让应用接管 PID 1 |
典型使用场景
- 固定启动入口:业务镜像只允许以指定程序启动,参数由运行时给
- 初始化脚本:入口先渲染配置、等待依赖就绪,再 exec 转交应用
- 命令行工具镜像:入口就是工具本身,run 后面直接接工具参数
- 调试排障:用 --entrypoint 临时换成 shell 进入容器检查文件
- 多模式镜像:一个入口脚本根据参数决定跑 web 还是 worker
组合与脚本入口
组合与脚本入口
# 定入口、给默认参数:run 尾部命令只覆盖 CMD 部分
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
CMD ["nginx", "-g", "daemon off;"]
# 调试时临时换掉入口
docker run --entrypoint /bin/sh -it myimage入口脚本正确转交
入口脚本正确转交
#!/bin/sh
set -e
# 准备配置、等待依赖就绪……
exec "$@" # 用 exec 让应用接管 PID 1,停止信号可直达入口写法对照
| 写法 | 信号可达 | CMD 参数 | 建议 |
|---|---|---|---|
| exec 数组形式 | 可达,应用为 PID 1 | 正常追加 | 推荐 |
| shell 形式 | 先到 shell,应用可能收不到 | 会被忽略 | 避免使用 |
| 脚本加 exec "$@" | 可达 | 正常转交 | 推荐 |
| 脚本不加 exec | 不可达,停机靠超时强杀 | 转交但进程非 PID 1 | 需要修正 |
shell 形式的 ENTRYPOINT 会忽略 CMD 参数(参数被 shell 吞掉),这是「CMD 写了却没有生效」的经典原因,排查时优先检查入口写法。
入口脚本里做初始化是对的,但最终一定要用 exec 转交:只有让应用成为 PID 1,才能正确接收停止信号并优雅退出,否则每次停机都会等到超时才被强杀。