Docker Compose 5.6 加了个 jobs。
很多人第一反应是:Compose 终于能跑定时任务了?
不是。
一句话讲清楚:这版的 job,就是把 docker compose run 从命令行搬进 compose 文件,外面套一个 triggers 字段。没有调度器,没有队列,没有重试。
10 月初发的。release notes 里对 job 的描述就一句,部分支持,仅手动触发的 job 可用。这句话其实已经把话说完了,只是很多人没往下看。
写一个 job,triggers 是必填的
不写 triggers,文件直接解析不过,报的是 job 缺 triggers 属性。写 manual: true 才通过校验。
白话版这样:
jobs:
migrate:
triggers:
- manual: true
一个自己都明说还在部分支持阶段的功能,唯一那个开关却是必填。这个设计我不太买账。留个位置可以,别把必填写死。
只有 docker compose run 能起一个 job
这条最容易漏。
up -d 把 db 起来了,然后打一句警告,说 job 不会被 up 启动,要用 run 触发,退出码 0。ps -a 里也找不到那个 job 容器,运行中、失败、等待,三个状态都没有。
create 和 start 直接拒,退出码 1,报「job 只能用 docker compose run 触发」。
所以它和 service 不是一类东西。service 讲的是起不起来,job 讲的是跑不跑一次。这一版只把后者做了一半。
schedule 触发器不能用,而且会拖垮整个文件
这版里最难受的地方。
加一个 schedule 的 job,up -d 直接中止,连那个不相干的 db 都不起,退出码 1,报「本版本不支持定时 job」。
一个手动 job,up 顶多警告一句然后跳过。一个带 schedule 的 job,能把整个 compose 文件判死。
这个差别很要命。CI 或者部署脚本里只要碰一下这个文件,全线不通。有人在评论里说,光校验 compose 文件的 CI 步骤是能过的,问题要到部署那一刻才爆。作者承认没拿 nightly 那个文件跑过 config,猜 config 会放行、up 会拒,说要去测。这条我标一下,等结论。
jobs 对 config --services 是隐形的
docker compose config --services 只列 db。job 不在里面。
所有靠这个命令的输出去遍历的脚本,都会安静地漏掉 job。这种静默比报错难查,报错至少有人告诉你哪里不对。
退出码原样透传
job 退 17,docker compose run 就返回 17。
这是这版里我觉得做对了的地方。CI 里靠退出码判失败,是最低要求,它做到了。
同一个 job 并发跑两次,就是两个容器
没有锁,没有排队,没有串行化。两个容器名不同,各自跑完,各自被 --rm 清掉。
对一次性脚本是好事。对数据库迁移脚本,这不叫特性,这叫事故的预备动作。
job 自己的 profiles 会自动激活
job 上写了 profiles: [migrations],run 的时候自动生效,命令行不用带 --profile。
小细节,但顺手。
没带 --rm 的容器,down 和 rm -f 都清不掉
跑完留下的容器,docker compose down 带不走,docker compose rm -f 也带不走。
这条得说清楚,免得冤枉人。同样的现象在 profiles 保护下的普通 service 上也一样。老毛病,jobs 继承了它,不是它引入的。但它会咬到第一次用 jobs 的人。
那组冷热启动的数字,别拿去估算
作者测了三冷三热。冷启动平均 1.717 秒,热 1.487 秒,差 230 毫秒左右,约 15%,归因到「起依赖容器」这件事上。
这条我只看懂一半,先放在这里。他的测试 db 是个 alpine 睡眠 600 秒的容器,started 和 ready 是同一个时刻。所以那 230 毫秒只是起一个空容器的成本,不是等数据库能连上的成本。真换成 Postgres 加 pg_isready,这个数会差好几倍。他自己后来也认了,说那段要改,还说要用 Postgres 补测。
在他补完之前,任何拿 230 毫秒做的估算都不成立。
还有一条没验证的
depends_on 的短写法走的是默认的 service_started,不是 service_healthy。对着真数据库的 job,可能在数据库还没接连接的时候就开始跑,冷启动时直接失败。
长写法的 service_healthy 他没拿 job 测过。这条我觉得比那 230 毫秒重要得多。等补测。
这期就收了一条,因为其他的我讲不清楚。
上面有任何一条你试过、或者觉得我讲错了,欢迎告诉我。讲错的我补,没讲清的我改。
本周就这些,下周见。
