用 entrypoint 做启动前检查可确保检查总被执行,因 cmd 会被 docker run 参数覆盖而 entrypoint(尤其 exec 形式)始终先运行再传参;典型脚本检查环境变量、服务连通性、配置文件,最后 exec "$@" 启动主进程并成为 pid 1。

用 ENTRYPOINT 做启动前检查,核心是把检查逻辑写进一个可执行脚本,并通过 ENTRYPOINT 指向它;检查通过后再用 exec "$@" 交出控制权给真正的应用命令。
为什么不用 CMD 做检查?
CMD 是默认运行命令,但会被 docker run 后面的参数完全覆盖,无法保证检查总被执行。而 ENTRYPOINT(尤其是 shell 形式或配合 exec 的 exec 形式)能确保脚本始终先运行,再把后续命令作为参数传入,稳定性更高。
典型检查脚本结构(推荐 exec 形式)
写一个 entrypoint.sh,放在镜像里并赋予可执行权限:
- 检查必要环境变量是否设置(如
DB_HOST、REDIS_URL) - 尝试连接依赖服务(如用
nc -z或curl -f测试端口连通性) - 验证配置文件是否存在且可读
- 所有检查通过后,必须用
exec "$@"启动主进程(否则容器会因脚本退出而停止)
Dockerfile 中的正确写法
避免使用 shell 形式的 ENTRYPOINT(如 ENTRYPOINT sh entrypoint.sh),因为它会绕过 PID 1 机制,导致信号无法正常传递给应用。推荐写法:
COPY entrypoint.sh /usr/local/bin/entrypoint.sh RUN chmod +x /usr/local/bin/entrypoint.sh ENTRYPOINT ["entrypoint.sh"] CMD ["your-app", "start"]
这样 docker run myapp 会执行 entrypoint.sh your-app start,检查完再 exec your-app start,主进程成为 PID 1。
常见陷阱提醒
不要在 entrypoint 脚本里用 sleep 或循环重试太久——这会让容器启动变慢甚至超时失败。建议设合理超时(如最多重试 5 次,每次间隔 2 秒)。
别忘了 set -e 或显式判断返回值,否则检查失败也会继续往下走。
如果应用本身是 shell 脚本,注意 shebang 和解释器路径是否在镜像中存在(比如用了 #!/usr/bin/env bash,但基础镜像只有 sh)。










