bigywater.tech
Docker · 63

depends_on 与健康检查:start 顺序不等于 ready

depends_on 写了就能保证 db 准备好了吗?service_healthy 和 service_completed_successfully 又是怎么回事?这篇用一个故意延迟就绪的 db 和一个会失败的一次性任务,量出三种写法下的真实启动顺序和时间差。

0.10 秒
只写 depends_on 时,web 比 3 秒后才就绪的 db 晚启动的时间
3.61 秒
service_healthy 下,web 比 db 晚启动的时间
退出码 1
依赖的一次性任务 exit 1 时,docker compose up -d 的退出码(web 停在 Created)

只写 depends_on

实测 · 本机执行输出
  docker compose up -d:退出码 0,用时 0.4 秒;输出中的状态行:Container bwlab-c58a-db-1 Creating | Container bwlab-c58a-db-1 Created | Container bwlab-c58a-web-1 Creating | Container bwlab-c58a-web-1 Created | Container bwlab-c58a-db-1 Starting | Container bwlab
  db 与 web 的启动时间差(web 晚于 db 多少秒):0.10 秒(db 要 3 秒后才就绪)

短写法的 depends_on: [db] 只控制启动顺序:db 容器启动后,web 立刻跟着启动(晚 0.10 秒),不管 db 里的程序有没有就绪。应用要自己重试连接,或者用 condition。

service_healthy

实测 · 本机执行输出
  docker compose up -d:退出码 0,用时 3.9 秒
  db 与 web 的启动时间差:3.61 秒;db 的健康状态:healthy

需要 db 定义 healthcheck。web 会等到 db 变成 healthy,docker compose up -d 也一直等到那时才返回(3.9 秒)。健康检查的 interval 影响等待的颗粒度。

service_completed_successfully

实测 · 本机执行输出
  job 退出码 0:docker compose up -d 退出码 0,用时 2.4 秒;web 容器:Up Less than a second;输出里的错误:Container bwlab-c58c0-job-1 Exited
  job 退出码 1:docker compose up -d 退出码 1,用时 2.4 秒;web 容器:Created;输出里的错误:Container bwlab-c58c1-job-1 Error service "job" didn't complete successfully: exit 1

适合数据库迁移、初始化这类一次性任务。任务成功退出,web 才启动;任务失败,compose 报错并以 1 退出,web 容器被创建但不启动。

连带启动

实测 · 本机执行输出
  只指定启动 c:启动了 ['bwlab-c58d-a-1', 'bwlab-c58d-b-1', 'bwlab-c58d-c-1']
  --no-deps 只启动 c:启动了 ['bwlab-c58d-c-1']

启动 c 会把它依赖的 a、b 一起启动;--no-deps 跳过依赖。

分步演示

depends_on 条件
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Docker Desktop(Engine 29.8.2,容器跑在 Docker Desktop 自带的 Linux 虚拟机里,内核与宿主机的 macOS 不同);镜像为 linux/arm64;需要看虚拟机内部时用特权容器 + nsenter;计时用 time / date +%s%N,数字每次运行会有小幅抖动。Docker Compose v5.5.1;用 alpine:3.20 与 sh 脚本模拟 db 的延迟就绪;启动时间取自 docker inspect 的 State.StartedAt,时间差取两个容器之差;每种情形运行一次;compose 项目名都以 bwlab 开头,实验后已用 compose down -v 和清理脚本删除
    • 没有验证:restart: true 的依赖更新行为、required: false、跨 profile 的依赖、依赖服务重启时 web 的行为、真实数据库的就绪判断、service_started 的显式写法(与短写法等价,我没有逐项对比)
    京ICP备2026067502号-1京公网安备11010502063487号