人们谈起 Dagger,最容易流传的一句,仍旧是某种版本的“CI/CD as code”。这句话足够醒目,却把更有用的那层意思遮住了。顺着 README 和官方文档往里看,Dagger 更适合被理解成一套面向软件交付的自动化运行时:构建、测试、发布、校验这些步骤,被写成带类型的函数与模块,可以在本地、CI,或者云端控制面上用同一套逻辑运行,并在每个执行场所复用同一份流程。[1][2] 它真正想做的,是把交付逻辑从脆弱的 shell 片段与平台私有 YAML 里抽出来,放进一个可复用的程序表面。
把话题放在 2026 年,这层理解更站得住,因为项目已经有了足够可见的维护热度,看起来更像一条正在工作的版本线。以 2026-04-16T17:05:30Z UTC 为准,GitHub API 显示 dagger/dagger 仓库有 15,669 stars、856 forks、72 个 open issues,最近一次 push 时间是 2026-04-16T16:07:00Z。[7] 公开发布节奏也很活跃:v0.20.6 在 2026-04-16 发布,前一版 v0.20.5 在 2026-04-09 发布,v0.20.4 也在同一天更早时刻发出。[8] 这些数字本身无法替代架构判断,却足以说明,这是一条仍在推进的核心版本线。
配图说明:题图没有选终端截图,也没有选泛化的 DevOps 舞台照,而是放了一张 Solomon Hykes 的真实 GitHub 肖像。这个选择合适,因为本文关心的是项目边界与方向。只有当运行时、模块系统与可移植性承诺继续维持在同一个框架里,Dagger 才会长期有意义。[10]
这个项目真正改变了什么
README 的表达很直接。Dagger 把 shell 脚本与专有 YAML 视作现代软件交付里已经不够好的基础,然后把自己概括为四个性质:programmable、local-first、repeatable、observable。[1] 官方 overview 文档继续把这四个词拆成具体对象:types、functions、modules、CLI、engine and API、SDKs,以及补充开源核心的可选云端能力。[2] 这一组对象很重要,因为它说明 Dagger 关心的核心,在于建立一套带自己对象模型的运行时。
真正的架构变化也正在这里。传统 CI 产品往往把工作流逻辑牢牢绑在自己的执行表面上,于是同一段逻辑在本地与平台内会呈现两种生活。Dagger 试图把顺序倒过来:工作流逻辑先写进同一套 API,再让不同执行位置去承接它。[1][2][3] 团队若把一个构建步骤或校验步骤写出来,期待得到的回报,也就不只落在配置文件更漂亮这一层;这一步既能在本地调试时直接调用,也能在今天的某家 CI 平台里运行,将来换到另一家时继续存在,还能被别的模块复用。
这也解释了,为什么 Dagger 更像应用代码,而不像流水线配置。Functions 文档写得很清楚:函数在 Dagger Engine 拉起的容器里执行,可以调用核心 API,也可以调用其他模块,开发者则通过可用 SDK 用常规编程语言来写这些函数。[3] 这套设计的意图,是让交付逻辑像代码一样拥有可组合的边界,脱离一次性 runner 指令列表那种被平台格式牵着走的形态。
模块系统把 Dagger 推进到可复用平台这一层
模块系统是 Dagger 从“更易上手的 runner 接口”走向“可复用交付平台”的关键一步。模块初始化文档显示,一个模块本身就是一份源码包,带着自己的 runtime container、language-native packaging,并支持从 Git 仓库远程获取模块。[4] 2024 年 InfoQ 关于 Dagger Functions 与 Daggerverse 的报道,也把这层变化从外部解释得很清楚:函数可以被打包成可复用模块,能直接从 CLI 调用,托管在 Git 中进行版本管理,而且由于底层通过生成出来的 API 暴露能力,不同语言写成的函数仍然可以彼此组合。[9]
这件事的分量在于,许多“pipeline as code”产品谈复用时,最后落到的仍是片段、模板、actions,类型边界和发现能力都不算稳。Dagger 的下注更重一些,它把交付逻辑当作更接近软件包的东西来处理。远程模块可以直接从 Git 调用,依赖可以被钉住,函数也因此有机会成为团队跨仓库共享的稳定单元。[4][9] 复杂度当然还在,只是它被搬进了一个更适合版本化、测试与推理的接口表面里,摆脱了四处散落、彼此牵连的 YAML include 结构。
近两年的 toolchain 与 check 概念,又把这条路再往前推了一步。Toolchains 文档把它定义为可安装的预构建工具与 checks,用来在单个项目或多个仓库之间标准化常见任务;checks 文档则把校验明确写成一等函数,直接进入工作流表面。[5][12] 这对工程组织是一个高杠杆入口。团队若想把 lint、test、scan、policy verify 这些动作统一起来,又不想让每个仓库都学一套略有偏差的 runner 方言,这套做法就很有吸引力。
本地优先的一致执行,才是最有穿透力的采用理由
真正让人关心 Dagger 的,更多落在调试成本这一层。README 说得很明白:它只要求一个 Linux 容器运行时,同时强调本地与 CI 的行为应该保持一致。[1] Functions 文档进一步解释,这种一致性是怎么来的:执行发生在沙箱容器里,主机访问必须显式传入,隐藏的环境依赖会被直接暴露出来。[3] Caching 文档则补上了性能这一面,说明 Dagger 会缓存 layers、volumes,以及 function calls 的结果,只要输入没有变化,重复运行就可以跳过一部分工作。[6]
这时,Dagger 也就从对 YAML 的审美抱怨里走了出来。许多交付链条上的痛点,本质上都是一致性痛点。某个 job 在 CI 里能过,在开发者电脑上却难以复现;某个发布步骤依赖 runner 上看不见的状态;某个安全扫描明明存在,却只能在远端 job 里跑,开发者直到很晚才会碰到。Dagger 的 local-first 模型,正是想把这条裂缝缩窄,让同一套工作流能在你调试它的地方被直接调用。[1][3][6] 对合适的团队来说,这带来的收益,落在构建与发布机器本身的迭代速度变快。
代价也同样清楚。Dagger 引入了一个新的运行时边界,而且它默认团队愿意把容器当成交付逻辑的中性执行底座。[1][3] 若某个仓库足够小,CI 表面也足够简单,靠普通脚本已经拿到了可以接受的本地可复现性,Dagger 就有机会显得抽象多于缓解。只有当工作流本身已经够长、够跨语言、够需要在多个仓库之间共享时,复用与一致执行的价值才会压过“尽量少一层”的冲动。
最适合谁,边界在哪里,怎样试才合适
《Adopting Dagger》这篇文档的价值,在于它把迁移路径写得很实在:先做 proof of concept,再做 incremental expansion,随后把最可复用的函数拆成独立模块,随着采用面扩大再继续外放。[11] 用这个路径评估项目,本来就是最合理的。Dagger 最适合的团队,通常同时具备几种条件:构建链条本身有多步骤、多语言或多仓库共享的特征;安全或策略检查希望在本地与远端保持同一种执行;工程组织也确实想把交付逻辑从单个平台的配置语法里拿出来。[5][6][9][11][12]
弱适配场景也必须摆出来。若团队真正需要的只是一个简单的托管 job runner,Dagger 反而会显得绕。若团队不愿把容器化执行当作基底,它那套可复现性叙述也就失去大半支撑力。[1][3] 若工作流小到平台原生 YAML 虽然不舒服,却还没有形成结构性成本,模块与运行时这套模型就会显得跨得太大。项目导论最有用的时候,不在于不断扩大“适合谁”,而在于把“不适合”的边界也画出来。Dagger 的那条边界,不在可移植性,而在免费简单。
所以,在 2026 年重新看 Dagger,一个更窄却更有力的说法会比口号更准确。它更像一套开源运行时,试图把软件交付逻辑写成可组合、可检查、可在不同执行位置一致运行的对象。[1][2][3][4][5][6][12] 若你的组织反复遇到复制粘贴的流水线逻辑、难以本地复现的 job、以及被平台隔开的工作流孤岛,这就是一项值得认真读进去的提案;若这些问题还没有长到那个地步,Dagger 依然有趣,只是尚未必要。
来源
- Dagger README - 项目定义、programmable/local-first/repeatable/observable 这组核心表述、容器运行时要求,以及功能概览。
- Dagger 文档,《Overview》 - types、functions、modules、engine/API、SDKs 与整体产品形状。
- Dagger 文档,《Functions》 - 函数执行模型、沙箱容器运行时、显式主机访问,以及可复现性的技术理由。
- Dagger 文档,《Module Initialization》 - 模块结构、runtime container、language-native packaging,以及 remote modules 支持。
- Dagger 文档,《Toolchains》 - 可安装的预构建工具与 checks、团队实践标准化,以及 CI 集成。
- Dagger 文档,《Built-In Caching》 - layers、volumes 与 function-call caching。
- GitHub API 中
dagger/dagger的仓库快照 - 文章写作时的 stars、forks、open issues 与最近 push 时间。 - GitHub API 中
dagger/dagger的 release 列表 - 最近核心版本标签与发布时间。 - InfoQ,《Dagger Enables Developer Functions for CI/CD and Opens the Daggerverse》 - 来自外部媒体的总结,涉及可复用函数、模块、CLI introspection 与基于 Git 的分发方式。
- Solomon Hykes 的 GitHub API profile,其中包含本文题图所用头像的来源。
- Dagger 文档,《Adopting Dagger》 - proof of concept、渐进扩展,以及把可复用函数继续拆成共享模块的建议。
- Dagger 文档,《Checks》 - 把校验写成可调用工作流函数,以及与共享 toolchains 的配合方式。