depends_on 写了就能保证 db 准备好了吗?service_healthy 和 service_completed_successfully 又是怎么回事?这篇用一个故意延迟就绪的 db 和一个会失败的一次性任务,量出三种写法下的真实启动顺序和时间差。
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。
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 影响等待的颗粒度。
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 跳过依赖。