depends_on 不起作用是因为它只控制容器启动顺序,不等待服务就绪;需配合 healthcheck 和 condition: service_healthy 实现真实依赖等待。

docker-compose.yml 里 depends_on 不起作用?
它真不起作用——depends_on 只控制容器启动顺序,不等服务就绪。比如数据库容器已 Up,但 MySQL 进程还在初始化、监听端口没开、健康检查没通过,Web 容器就可能因连接拒绝直接退出。
解决办法是搭配健康检查 + 条件依赖:
- 给被依赖服务(如
db)加healthcheck,用mysqladmin ping或curl -f http://localhost:8080/actuator/health等真实探测其可用性 - 在依赖方(如
web)的depends_on中写明条件:condition: service_healthy -
interval建议设为5s,timeout至少20s,retries别少于10,避免误判
服务启动后立刻退出,日志显示 connection refused
这基本锁定为上游服务未真正就绪,或网络不通。先别改代码,按顺序查:
- 执行
docker-compose ps,确认所有容器状态是Up而非Exit或Restarting - 对疑似问题服务运行
docker-compose logs <service></service>,重点看最后一屏——是否报Connection refused、timeout或no route to host - 进容器手动测试连通性:
docker-compose exec db sh -c "nc -zv web 80"(反向验证),或从web容器里telnet db 3306 - 注意:Docker Compose 默认为每个项目建独立桥接网络,服务名即 DNS 名,不用写
localhost;若用host.docker.internal,Windows/macOS 上才默认可用
docker compose up 卡住、无响应或部分服务没拉起来
常见原因是环境没准备好,不是配置本身错。优先检查三件事:
- Docker Desktop 必须运行中(任务栏图标绿色),且 WSL2 后端已加载——打开 PowerShell 执行
wsl -l -v,确认发行版状态是Running,不是Stopped - 确认没手动设置错误的
DOCKER_HOST:Linux/macOS 运行echo $DOCKER_HOST,Windows 运行echo %DOCKER_HOST%,非空时建议临时unset DOCKER_HOST或删掉该变量 - 检查本地端口是否被占:比如
ports: ["8080:80"],宿主机 8080 被 Chrome 或另一个 Nginx 占了,web就会启动失败;用lsof -i :8080(macOS/Linux)或netstat -ano | findstr :8080(Windows)确认
用了 healthcheck 仍失败,或者 condition 写了却没生效
有两个隐蔽点容易漏:
-
healthcheck.test命令必须在容器内可执行。例如 MySQL 镜像里有mysqladmin,但 Alpine 版本的镜像默认没装,得自己apk add mysql-client或换用debian基础镜像 -
depends_on的condition仅在docker-compose up时生效,docker-compose start不触发等待逻辑——后者只负责启停容器,不处理依赖条件 - 如果服务用的是自定义网络(
networks:下声明),确保所有依赖服务都在同一网络里;跨网络通信需显式external: true或额外配置
最常被忽略的是健康检查命令的执行上下文——它跑在容器内部,路径、环境变量、权限都受限,不能假设和你 exec 进去时一样。先手动进容器跑一遍 healthcheck.test 里的命令,再决定要不要加 sh -c 包一层。


















