Docker 显示 unhealthy,网页却能打开

读取容器健康检查的命令与输出,再查工具、端口、路径和认证。unhealthy 不会必然触发普通 Docker 重启策略。

网站能打开,Docker 却显示 unhealthy,先看检查命令和最近输出。浏览器走公网入口,容器检查用的是内部地址,两边的端口、路径、工具或认证条件可能不同。

读取实际检查配置和最近结果

假设服务名为 web,以下命令只读状态:

docker compose ps
docker inspect --format '{{json .Config.Healthcheck}}' \
  "$(docker compose ps -q web)"
docker inspect --format '{{json .State.Health}}' \
  "$(docker compose ps -q web)"

第二条确认实际执行什么,第三条看退出码与最近的 Log。没有 Health 数据时,先核对容器是否正确、是否真的配置了检查。镜像自带的检查也可能被 Compose 覆盖。

检查输出应当先查什么
找不到 curl最终运行镜像是否包含该工具
Connection refused容器内部端口、监听地址和启动时间
404 或 401URL 是否存在、是否需要认证
超时端点是否卡在依赖调用,检查时间是否合理
变量变为空Compose 展开与容器环境是否混淆

检查里的 localhost 指当前容器。宿主机映射 8080:3000 时,容器内部通常检查 3000,而不是宿主机 8080;host 网络等特殊模式要另行判断。

按应用内部端口配置检查

应用监听内部 3000、/health 无需认证,并且运行镜像已有 curl 时,可以参考:

healthcheck:
  test: ["CMD", "curl", "--fail", "--silent", "--show-error", "--max-time", "3", "http://127.0.0.1:3000/health"]
  interval: 30s
  timeout: 5s
  retries: 3
  start_period: 30s

--fail 使 HTTP 400 及以上响应返回失败;重定向或错误内容返回 200,仍可能通过。业务需要严格检查时,要核对期望状态码或响应字段。

CMD 不执行 shell 变量展开。需要变量、管道或 && 时使用 CMD-SHELL,并确认运行镜像有 shell;保留给容器展开的美元符号,在 Compose 中写成 $$。宽限期用于容忍启动阶段失败,不会修复错误的检查地址。

unhealthy 会自动重启吗

普通 Docker 重启策略针对进程退出,不能假定 unhealthy 就会自动重启容器。关闭检查也不会修复应用,只会停止报告这项状态。需要添加工具时修改最终镜像,避免临时装进运行容器后,下次重建又丢失。

保存原配置再部署,观察多个检查周期的新记录退出为 0,同时验证实际业务入口。若日志显示 OOM 等资源问题,再按内存配置选择安排增配;工具缺失、错误 URL 或认证失败,应先在当前机器上修正。

日志显示正常业务长期资源不足时,再按应用、数据库和更新峰值一起选规格。可比较 Evoxt 的内存与地区,或查看 雨云 RCS 的配置选项,先短期运行同一份应用观察结果。镜像缺 curl、探针端口错误或认证不符时,在现有实例修检查命令即可,别因检查失败就直接升级服务器。