跳到主要内容
Compose 5.6 的 jobs,说到底就是把 docker compose run 写进配置文件

Compose 5.6 的 jobs,说到底就是把 docker compose run 写进配置文件

阿简
阿简

· 阅读约 4 分钟

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 毫秒重要得多。等补测。

这期就收了一条,因为其他的我讲不清楚。

上面有任何一条你试过、或者觉得我讲错了,欢迎告诉我。讲错的我补,没讲清的我改。

本周就这些,下周见。

阿简
阿简

每周替你把 vibe-coding 圈的大事筛成一张小抄,被讲玄的概念一句话搞懂。

查看主页 →