Docker 调试容器时,先用 healthcheck 看服务是不是真的可用

35 次浏览3 条回复

容器显示 running,不等于应用已经能接请求。临时排查时可以在 compose 里加一个简单的 healthcheck,让状态里直接看到服务是否通过检查。

环境:Docker Compose v2,示例用 nginx。新建 compose.yml:

services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
    healthcheck:
      test: ["CMD-SHELL", "wget -q -O /dev/null http://127.0.0.1/ || exit 1"]
      interval: 5s
      timeout: 2s
      retries: 3

启动后看状态:

docker compose up -d
docker compose ps

等一会儿,STATUS 里会出现 healthy。也可以直接看检查记录:

docker inspect --format='{{json .State.Health}}' $(docker compose ps -q web)

真实项目里把地址和依赖换成应用自己的健康接口就行。检查命令最好只判断服务是否能正常响应,别把太多外部依赖都塞进去,不然一个无关的依赖故障也会让容器看起来像挂了。

补一个小点:如果服务启动本来就慢,可以加 start_period,不然刚启动那几十秒可能会被连续判失败。

比如数据库迁移、预热缓存这种场景,先给它一点启动缓冲,再让 retries 接管,会少很多误判。

还有个配套用法是本地 compose 里让依赖等到 healthy 再启动,比如 app 等 db:

services:
  app:
    depends_on:
      db:
        condition: service_healthy

这个只适合开发环境里减少启动顺序的干扰。线上还是得让应用自己能处理依赖短暂不可用,不然健康检查通过了也可能在后面抖一下。

排查失败原因时还可以直接看最近一次 healthcheck 的输出,省得只盯着 unhealthy 猜:

docker inspect --format='{{range .State.Health.Log}}{{.ExitCode}} {{.Output}}{{end}}' $(docker compose ps -q web)

如果输出太挤,也可以先 docker inspect 看完整 JSON。小脚本里我会尽量让检查命令失败时打印一点明确原因,比如连不上端口还是 HTTP 状态不对。