dagger 不适合直接“引入”进 go 项目,因为它不是 go 库,无法用 go get 安装或 import,而是需作为外部 cli 工具安装并集成到工作流中,通过 dagger do 调用定义的函数。

为什么 Dagger 不适合直接“引入”进 Go 项目
Dagger 是一个独立的 CI/CD 引擎,不是 Go 的库或 go mod 可管理的依赖。你无法用 go get 安装它,也不能在 main.go 里 import "dagger.io/dagger" —— 它没有 Go SDK(官方不提供,社区实现不稳定且不被推荐)。所谓“引入”,本质是把 Dagger 当作外部工具链集成进你的 Go 项目工作流,而非语言级依赖。
本地安装 Dagger CLI 并验证是否可用
所有 Dagger 流水线都靠 dagger CLI 驱动,必须先在开发机或 CI 环境中装好它。Go 项目本身不感知 Dagger,但构建脚本和 CI 配置需要调用它。
- macOS:用 Homebrew 运行
brew install dagger/tap/dagger - Linux/macOS 手动:下载二进制并加到
$PATH,例如curl -L https://dl.dagger.io/dagger/install.sh | sh - 验证:运行
dagger version,输出应含版本号;再跑dagger init看能否生成dagger.json
注意:Dagger CLI 依赖 Docker 或 Podman(需后台 daemon 运行),dagger version 报错 Cannot connect to the Docker daemon 就说明容器运行时没起来,不是 Dagger 问题。
用 dagger init 生成基础配置并适配 Go 构建场景
dagger init 会创建 dagger.json 和默认 dagger/main.go(基于 Go SDK 模板),但这只是起点。你需要手动改写函数逻辑,让它真正 build 你的 Go 服务。
- 确认
dagger/main.go中的Build函数调用的是你项目的go build命令,而不是模板里的 demo 代码 - 用
WithExec([]string{"go", "build", "-o", "./bin/app", "."})替换默认命令,路径要匹配你项目结构 - 如果用
CGO_ENABLED=0静态编译,得显式设置:WithEnvVariable("CGO_ENABLED", "0") - Go module 路径需与
go.mod一致;Dagger 默认工作目录是项目根,若go.mod在子目录(如src/),要用WithWorkdir("src")
示例片段:
func (m *Main) Build(ctx context.Context) (*File, error) {
return dag.
Container().
From("golang:1.22-alpine").
WithMountedDirectory("/app", dag.WorkingDirectory()).
WithWorkdir("/app").
WithEnvVariable("CGO_ENABLED", "0").
WithExec([]string{"go", "build", "-o", "./bin/app", "."}).
File("./bin/app")
}
CI 中调用 dagger do 而不是 go run
GitHub Actions / GitLab CI 里不能写 go run dagger/main.go —— Dagger 流水线必须通过 dagger do <func></func> 触发。这是最常被忽略的点:很多人以为写个 Go 文件就能直接跑,结果 CI 报错 command not found: dagger 或 no function named 'Build'。
- 确保 CI 步骤先安装
daggerCLI(用 setup-dagger action 或手动 curl) - 用
dagger do build调用函数(函数名默认小写,除非用//+dagger:output注释覆盖) - 函数参数需显式传入:比如
dagger do build --target-arch amd64对应func Build(ctx context.Context, targetArch string) - 输出文件用
--output ./dist/app保存,后续步骤才能用
复杂点在于:Dagger 函数返回 *File 或 *Directory,这些对象只在 Dagger 执行上下文中有效,不能直接当本地文件路径用。想存到 CI 工作区,必须显式调用 .Export() 或用 --output。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











