把 CI 脚本写进代码前,我会先用 Dagger 做一条本地可复跑流水线
很多团队的 CI 一开始都很朴素:几个 shell 脚本,一段 YAML,再加一点缓存配置。项目变大后,本地和 CI 的命令开始分叉,依赖缓存也变得难解释。Dagger 适合切入的地方,正是把测试、构建、发布这些交付动作收拢成可以本地复跑、可以组合、可以观察的工程接口。

同一组 Dagger 函数在开发机和 CI 中复跑,容器运行时与缓存层负责稳定执行环境。 来源:Codex image generation
先把交付动作函数化
Dagger 官方仓库把它描述为用于 build、test、ship 任意代码库的自动化引擎,可以在本地、CI 或云端运行。它的核心概念里,Functions 是最小构建块:接收 typed inputs,通常在容器里执行操作,再返回 typed outputs。对日常项目来说,test、build、publish 不需要只存在于 CI YAML 里,可以变成代码仓库中的函数。
我会先从一条最短链路开始:buildEnv 准备容器化构建环境,test 跑单元测试,build 产出构建结果,publish 在测试通过后再生成发布产物。Dagger 的 CI quickstart 也采用了类似拆分,并展示了 Go、Python、TypeScript、PHP、Java 等 SDK 写法。拆完后,每个函数都有明确输入和输出,本地调试可以单跑,CI 中也能复用同一套定义。
本地和 CI 共用同一条路径
Dagger 的本地优先价值在于减少环境分叉。官方 README 提到,自动化任务写好后可以在笔记本、AI sandbox、CI server 或专用云基础设施上运行,主要依赖是容器运行时。我的落地原则很简单:只要 CI 会跑的关键路径,开发机也要能用相同入口跑起来。
比如前端项目里,先把安装依赖、类型检查、单测、构建放入 Dagger function。开发在提交前跑 dagger call test 或 dagger check,CI 只负责在同一提交上调用同一组函数。这样失败差异会小很多,排障时也能把 CI 的输入条件拿回本地复现。
缓存要显式设计
CI 提速最容易变成玄学,原因通常是缓存边界没有被写清。Dagger 的内置缓存文档把缓存分成 layers、volumes 和 function calls。容器镜像构建过程会自动复用 layer;包管理器这类跨运行需要保留的数据,可以通过 cache volume 挂载;函数调用结果也可能在输入不变时复用。
这给小团队一个实用建模方式:把 npm、pip、maven 这类下载缓存放进专门的 cache volume,把源码目录、锁文件和环境变量作为函数输入,把构建产物作为函数输出。缓存命中与否可以从输入变化解释,后面换 CI 平台时也不会把逻辑绑死在某一家 YAML 语法里。
从只读校验开始迁移
我更建议先写 lint 和 test,只读源码,不发布任何东西。第二步再加入 build,把产物导出到本地目录或临时 registry。第三步才接入正式发布和凭据。Secrets、镜像仓库、云账号这些高风险输入,应当等函数边界稳定后再接。
如果团队已经有复杂 CI,可以保留原 YAML 作为调度层,让它只安装 Dagger CLI 并调用仓库里的函数。迁移过程中,每次只替换一个阶段,并记录旧命令、新函数、输入、输出和回滚方式。Dagger 的价值会在重复失败、跨机器复现和缓存解释上体现出来,前提是先把交付动作写得足够窄。
适合优先尝试的场景
我会优先在三类项目里试 Dagger。第一类是本地和 CI 经常不一致的前后端仓库。第二类是需要容器化测试环境的服务,比如测试时要启动数据库或临时服务。第三类是经常由 AI 或自动化代理改代码的项目,因为 agent 需要一个可复跑的质量入口,才能在生成补丁后自行跑检查。
Dagger 并不会替代排队、权限、审批和部署窗口这些 CI 平台能力。它更像是把交付过程里真正和代码相关的部分抽出来,变成一组可本地调用的函数。只要这层稳定,团队就能少维护一套隐形脚本,多保留一条可解释、可复跑的工程路径。
来源链接
Dagger Core Concepts: https://docs.dagger.io/core-concepts/
Dagger CI Quickstart: https://docs.dagger.io/getting-started/quickstarts/ci/
Dagger Built-In Caching: https://docs.dagger.io/features/caching/
GitHub dagger/dagger: https://github.com/dagger/dagger
Dagger Releases: https://github.com/dagger/dagger/releases