关键在于用带详细输出的诊断脚本配合 Docker 健康检查机制:在 HEALTHCHECK 中调用 /health.sh,脚本内用 echo 输出明确错误信息,通过 docker inspect 查看缓存的 Log 字段获取最近一次检查的 stdout/stderr,或挂载日志文件持久化记录。
要让 docker 容器健康检查输出详细的错误诊断日志,关键不是靠健康检查命令本身“打印日志”,而是通过合理设计 healthcheck 命令、结合容器内诊断脚本、并配合 docker 日志机制来捕获和暴露失败原因。
在 HEALTHCHECK 中调用带详细输出的诊断脚本
Docker 健康检查默认只关心命令退出码(0=健康,非0=不健康),不会自动记录 stdout/stderr。所以需把诊断逻辑封装成一个能输出清晰信息的 shell 脚本,并确保它在失败时打印具体原因:
- 在镜像中写一个
/health.sh,例如检查服务端口连通性 + API 响应状态 + 关键文件是否存在 - 每个检查步骤都用
echo "[INFO]..."或echo "[ERROR] failed to connect to DB: $output"明确标记上下文 - 脚本末尾用
exit 1表示失败,但 stdout 已包含可读错误信息 -
Dockerfile 示例:
HEALTHCHECK --interval=30s --timeout=5s --start-period=60s --retries=3 \ CMD ["/health.sh"]
用 docker inspect 查看最后一次健康检查的完整输出
Docker 会缓存最近一次健康检查的 stdout/stderr(仅限失败或超时时的部分输出,最多 4096 字节),可通过以下命令获取:
-
docker inspect <container> | jq '.[0].State.Health.Log'(需安装 jq) - 或直接看原始字段:
docker inspect <container> | grep -A 20 '"Log": \[' - 输出中能看到
"ExitCode"、"Output"(即脚本 echo 的内容)、"Start"和"End"时间戳
在脚本中主动记录到文件并挂载出来(适合深度排障)
如果默认 4KB 缓存不够,或你想保留历史记录,可在健康脚本中追加日志到文件:
- 脚本开头加
exec >> /var/log/health.log 2>&1,后续所有 echo 和命令输出都会落盘 - 启动容器时用
-v $(pwd)/health-logs:/var/log挂载日志目录到宿主机 - 这样即使容器重启,也能查
health.log看过去几次检查的完整上下文(比如证书过期、依赖服务响应慢等)
避免常见陷阱
- 不要在 HEALTHCHECK CMD 中用
|| echo "fail"这类管道——Docker 只捕获最后一条命令的 stdout,前面的 echo 会被丢弃 - 不要依赖后台进程日志(如 nginx error.log)——健康检查是独立执行的短时命令,无法自动读取其他进程的实时日志
- 超时时间(
--timeout)设太短会导致诊断脚本被 kill,看不到完整错误;建议设为略大于脚本最坏情况耗时 - 使用
--start-period给应用留足启动缓冲,避免容器刚起来就因初始化未完成而报错


















