健壮的 docker 健康检查需真实反映服务可响应性,应使用 curl/wget 访问轻量业务端点(如 /health),避免进程或端口级检测;脚本须自包含、独立于主进程;合理设置 --start-period、--interval、--timeout 和 --retries 参数,并按服务类型做最小必要依赖验证。
编写健壮的 docker 容器健康检查(healthcheck),关键不是写一个“能跑通”的脚本,而是让检查真正反映容器内服务是否 可响应、可处理业务请求。单纯检测进程是否存在或端口是否监听,容易产生误报(比如服务卡死但进程还在、端口通但 http 返回 503)。
用 curl 或 wget 做真实业务级探测
避免只用 nc -z localhost 8080 这类底层连接检查。应模拟真实客户端行为,访问一个轻量、稳定、带业务语义的健康端点(如 /health 或 /actuator/health)。
- 优先使用
curl -f -s -o /dev/null --max-time 3 http://localhost:8080/health:-f 确保非 2xx/3xx 状态码失败,--max-time 防止挂起 - 若容器内无 curl,可用 busybox wget:
wget --spider --timeout=3 --tries=1 -q http://localhost:8080/health - 避免检查根路径(
/),它可能触发重定向、渲染模板或 DB 查询,不够轻量也不稳定
健康脚本必须独立于主进程生命周期
HEALTHCHECK 指令执行的是独立 shell 进程,不能依赖主应用的环境变量、工作目录或临时文件。脚本要自包含、可重入。
在 Linux 上通过 Docker 运行 OpenClaw,并使用 Tailscale 实现远程访问。⚠️ 涉及 sudo、Docker、Tailscale和凭证挂载——请先查阅安全章节...
- 不要写
HEALTHCHECK CMD [ "sh", "-c", "ps aux | grep myapp || exit 1" ]—— 进程名模糊、grep 易误判、无法反映服务能力 - 推荐将检查逻辑封装为独立脚本(如
/health.sh),COPY 进镜像,并在 HEALTHCHECK 中调用:HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 CMD ["/health.sh"] -
/health.sh开头加#!/bin/sh -e,确保任一命令失败即退出;显式指定路径(如/usr/bin/curl),不依赖 PATH
合理设置 HEALTHCHECK 参数,适配启动与波动
默认参数对大多数 Web 服务过于激进,易导致容器反复重启。
-
--start-period:给慢启动服务(如 Spring Boot、Java 应用)预留时间,设为 20–60s,避免启动中就被判不健康 -
--interval:30s 是较稳妥值;高频检查(如 5s)会增加负载,且对瞬时抖动过度敏感 -
--timeout:建议 ≤5s;超过说明服务已无响应能力,不必等更久 -
--retries:3 次较合理;允许短暂网络抖动或 GC 暂停,但连续失败就该隔离
补充:健康脚本里做最小必要验证
根据服务类型加一层关键依赖校验,但务必轻量、快速、无副作用。
- Web API:检查
/health返回 JSON 中"status": "UP"(用jq -e '.status == "UP"' 2>/dev/null) - 数据库代理类容器:用
mysql -h127.0.0.1 -P3306 -uhealth -phealthpass -e "SELECT 1",但需提前建好专用健康用户 - 缓存代理:
redis-cli -h 127.0.0.1 -p 6379 PING | grep -q "PONG" - 切忌在健康检查中执行耗时操作(如查大表、生成报表、调用外部 API)










