关键在于服务真正就绪而非容器启动,docker compose通过healthcheck执行真实探测命令(如pg_isready、curl等)判断业务可用性,并配合depends_on: service_healthy控制启动顺序,但应用层仍需实现连接重试与健康检查。

关键不是等容器启动,而是等服务真正能干活。Docker Compose 的健康检查机制就是用来判断“服务是否就绪”,而不是“进程是否在跑”。它通过执行命令验证业务可用性,再配合依赖配置,让上游服务只在下游真正准备好后才启动。
给被依赖服务加 healthcheck
数据库、缓存这类基础服务必须自己声明怎么才算“就绪”。不能只看进程是否存在,得实际连一连、查一查。
- 用 test 指定真实探测命令:PostgreSQL 用
pg_isready,MySQL 用mysqladmin ping,Web 服务用curl -f http://localhost/health - start_period 很关键:PostgreSQL 初始化可能要 20–40 秒,这段时间内失败不计数,避免误判
- interval 和 timeout 要合理:比如每 30 秒查一次,单次超时设为 10 秒,连续失败 3 次才标为 unhealthy
在依赖服务里声明等待条件
上游应用(比如 API 服务)不能一上来就硬连数据库,得明确告诉 Compose:“等 db 健康了再启动我”。
- 用 depends_on + condition: service_healthy,不是
service_started - 这样
docker-compose up api会先拉起 db,等它状态变成healthy,再启动 api - 注意:这仅控制容器启动顺序,不代替应用内的连接重试逻辑
验证和排查状态
配置完别光靠猜,用命令确认服务是不是真健康了。
- 运行
docker-compose ps查看各服务的 HEALTH 状态列,显示healthy才算通过 - 详细信息用
docker inspect <container_id> --format '{{json .State.Health}}'</container_id>,能看到最近几次检查结果、时间戳和错误输出 - 如果一直卡在
starting或变成unhealthy,重点查 test 命令是否能在容器内正常执行、端口是否监听、权限是否足够
别忽略应用层的容错
Compose 的健康检查只管“启动阶段”的等待,它不会、也不能替你处理运行时问题。
- 网络抖动、数据库锁表、临时连接池满——这些都会导致应用启动后第一次连接失败
- 你的代码仍需实现带退避策略的重试(比如指数退避),或使用连接池自带的健康检测机制
- 把健康检查路径(如
/health)设计成真正反映业务就绪的状态,比如检查 DB 连通性 + 关键配置加载完成











