HEALTHCHECK 指令用于容器运行时主动检测服务可用性,需配置合理间隔、超时、启动延时和重试次数,并使用真实业务端点(如 curl -f /actuator/health)而非进程检查,避免权限、启动延迟和退出码错误等陷阱。

Docker 镜像中配置 HEALTHCHECK 指令,能让容器运行时主动汇报自身健康状态,帮助 Docker 守护进程或编排工具(如 Swarm、Kubernetes)及时发现异常并自动重启或隔离容器。关键不在于“加了就行”,而在于检查逻辑是否真实反映服务可用性。
HEALTHCHECK 基本语法与作用
HEALTHCHECK 是 Dockerfile 中的指令,必须写在镜像构建的最后阶段(通常紧贴 CMD 或 ENTRYPOINT 之前)。它不会影响镜像构建过程,只在容器运行时生效。
常用格式:
HEALTHCHECK [OPTIONS] CMD command其中 Options 可选:
- --interval=30s:两次检查间隔,默认 30 秒
- --timeout=3s:单次检查超时时间,默认 3 秒
- --start-period=40s:容器启动后等待多久才开始健康检查,默认 0 秒;对慢启动服务(如 Spring Boot、数据库)很重要
- --retries=3:连续失败多少次判定为 unhealthy,默认 3 次
选择真正有效的检查命令
健康检查不是“进程是否存在”,而是“服务是否可响应业务请求”。避免用 ps aux | grep myapp 这类伪检查。
推荐方式:
-
HTTP 服务:用
curl -f http://localhost:8080/actuator/health(Spring Boot)或/healthz(通用轻量端点),-f确保非 2xx/3xx 状态码返回非零退出码 -
TCP 服务:用
echo '' | nc -z localhost 5432检查端口连通性(PostgreSQL),但需注意:仅通端口 ≠ 服务就绪(如 DB 正在恢复) -
自定义脚本:将检查逻辑封装成
/health.sh,放入镜像并设为可执行,再在 HEALTHCHECK 中调用,便于复用和调试
避免常见陷阱
几个高频出错点:
-
检查路径未暴露或权限不足:确保检查命令中访问的端口、路径、文件在容器内可达,且用户有执行权限(比如用
curl但镜像没装) -
忽略启动延迟:Java 应用常需 10–30 秒初始化,若不设
--start-period,容器可能刚启就被判 unhealthy 并反复重启 - 检查太重或太轻:频繁调用 /metrics 或触发 DB 写入会影响性能;只检查进程存在则失去意义
- 未验证退出码:Docker 仅根据命令退出码判断(0 = healthy,非 0 = unhealthy),务必测试命令在异常时是否真返回非 0
验证与调试方法
构建镜像后,可通过以下方式确认健康检查是否生效:
- 运行容器:
docker run -d --name test-app myapp:latest - 查看状态:
docker inspect --format='{{.State.Health}}' test-app,输出含Status(healthy/unhealthy/starting)和Log(最近几次检查详情) - 手动触发检查:
docker container exec test-app curl -f http://localhost:8080/actuator/health,模拟 HEALTHCHECK 行为 - 日志排查:
docker logs test-app查看应用自身是否报错,常是健康失败的根本原因

















