健康检查失败不会自动重启容器,需组合healthcheck与restart策略并让容器实际退出才能触发重启。正确配置healthcheck参数,并通过应用主动退出或外部脚本使unhealthy状态导致容器停止,再由restart策略(如unless-stopped)执行重启。

健康检查失败时自动重启,不是通过 compose.yml 直接设置“失败就重启”,而是靠组合使用 healthcheck 和 restart 策略来实现。Docker 本身不会因为健康检查失败主动重启容器,但可以配置容器在退出(包括因健康检查失败被标记为 unhealthy 后手动或自动停止)时按策略重启。
1. 正确配置 healthcheck
定义合理的健康检查命令、间隔、超时和失败阈值,让 Docker 能准确判断服务是否异常:
-
test:必须是能反映服务真实状态的命令,比如
curl -f http://localhost:8080/health || exit 1 - interval:检查频率,太短易误判,太长恢复慢,建议 10–30s
- timeout:单次检查超时时间,应略大于服务正常响应时间
- retries:连续失败多少次才标记为 unhealthy(默认 3),建议设为 2–5
- start_period:容器启动后等待多久再开始检查,给服务预留初始化时间(如 30s)
2. 配合 restart 策略触发重启
健康检查失败本身不会杀掉容器,但你可以让容器在异常退出后自动重启。常用策略:
- restart: "unless-stopped":容器崩溃退出时重启,适用于希望长期运行的服务
- restart: "on-failure:5":只在非 0 退出码时重启,最多重试 5 次
- ⚠️ 注意:healthcheck 失败 ≠ 容器退出,所以需配合其他机制让容器真正退出
3. 让 unhealthy 触发实际退出(可选但推荐)
Docker 不会因 health status 变为 unhealthy 自动 stop 容器。若想“健康失败 → 停止 → 重启”,需外部干预。常见做法:
- 在应用内监听健康状态,或用轻量级监控脚本定期检查
docker inspect -f '{{.State.Health.Status}}' container_name,发现 unhealthy 后执行docker restart - 使用 healthcheck-restart 这类工具(非官方,需自行评估安全性)
- 更稳妥的做法:让应用自身在健康探针失败时主动 panic/exit(例如 Go 中 /health 返回 500 时触发 os.Exit(1)),这样容器自然退出,restart 策略生效
4. 示例 compose.yml 片段
一个典型 Web 服务配置:
services:
web:
image: my-web-app:latest
ports: ["8080:8080"]
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 20s
timeout: 10s
retries: 3
start_period: 40s
restart: unless-stopped
注意:这个配置下,容器仍需因某种原因(如应用主动退出、OOM、信号终止)停止,restart 才会生效。单纯 health status 变为 unhealthy 并不会触发重启。


















