Docker容器健康检查需通过HEALTHCHECK指令配置真实业务可用性检测,而非仅检查进程存活;应使用curl -f调用/health等业务端点、nc或自定义脚本验证服务状态,并合理设置--interval、--timeout、--start-period和--retries参数,配合restart策略实现自动恢复。

容器健康检查不是加个命令就完事,关键在于让 Docker 真正“看懂”你的服务是否能干活。配置得当,它就能在服务卡死、连接超时或接口返回 503 时自动重启,无需人工干预。
用 HEALTHCHECK 指令定义真实可用性检查
健康检查必须反映业务层面的可用性,而不是“进程还在不在”。比如 Web 服务,应调用 /health 或 /actuator/health 这类由应用暴露的真实端点;数据库服务,应执行简单 SQL 查询验证可连可读。
- 避免用
ps aux | grep myapp—— 进程活着不等于服务可用 - HTTP 类服务推荐
curl -f http://localhost:8080/health,-f 确保非 2xx/3xx 返回非零退出码 - TCP 类服务(如 Redis、PostgreSQL)可用
nc -z localhost 6379,但要注意:端口通 ≠ 服务就绪,建议配合轻量级业务探针 - 复杂逻辑可封装成脚本(如检查 DB 连接 + 磁盘空间 + 缓存响应),COPY 到镜像并设为可执行,再在 HEALTHCHECK 中调用
参数设置要贴合应用实际启动节奏
很多容器反复重启,不是服务真坏了,而是健康检查太急——Java 应用还没加载完 Spring 上下文,检查就已失败。start-period 就是为这类场景设计的缓冲期。
- --start-period=40s:给慢启动应用留足初始化时间,期间失败不计入重试计数
- --interval=30s:太频繁(如 5s)会增加负载;太宽松(如 5 分钟)故障发现滞后
- --timeout=3s:确保检查本身不拖慢主服务,超时即判失败
- --retries=3:连续 3 次失败才标记 unhealthy,避免偶发网络抖动误判
搭配 restart 策略触发自动恢复
Docker 本身不因 unhealthy 状态直接重启容器,必须配合 restart 策略才能实现“自愈”。这个策略是在运行时指定的,和 HEALTHCHECK 是协同关系。
-
--restart=unless-stopped:最常用,Docker daemon 重启后也自动拉起,适合长期服务 -
--restart=on-failure:5:仅在容器非零退出时重启,最多重试 5 次(适用于希望控制重启次数的场景) - 注意:unhealthy 不等于退出,所以
on-failure对健康检查失败无效;要用unless-stopped或always才能在状态变 unhealthy 后由编排工具(如 Swarm)触发重建
验证和调试不能跳过
配置完别急着上线,先本地验证命令行为是否符合预期——特别是异常情况下的退出码。
- 构建镜像后运行:
docker run -d --name test-app myapp:latest - 查状态:
docker inspect --format='{{.State.Health.Status}}' test-app,观察是否从 starting → healthy 或 unhealthy - 看详情:
docker inspect test-app | jq '.State.Health',检查 Log 字段里每次执行的命令、输出和退出码 - 手动模拟故障(如停掉内部服务),确认连续失败后状态变更,并观察是否按预期重启(需配合 restart 策略)


















