如何用 Dagger 从 Dockerfile 构建镜像并发布到私有镜像仓库
【免费下载链接】daggerAutomation engine to build, test and ship any codebase. Runs locally, in CI, or directly in the cloud项目地址: https://gitcode.com/GitHub_Trending/da/dagger
如果你的代码仓库里已经有一份 Dockerfile,希望用它构建镜像,并把结果推送到需要账号密码的私有镜像仓库(例如 Docker Hub、GitHub Container Registry),Dagger 的 cookbook 提供了可以直接组合的两块能力:Directory.DockerBuild从 Dockerfile 构建镜像,以及WithRegistryAuth+Publish携带仓库凭据发布到私有 registry。本文把这两块拼成一条完整路径:编写一个 Dagger 模块函数,从指定目录读取 Dockerfile 构建,然后发布到你自己的私有仓库。
以下示例以 Go SDK 编写,文档同时提供了 Python、TypeScript、PHP 版本,对应代码见文末参考链接。运行前需要环境中已安装daggerCLI,并把下面的函数放入一个 Dagger 模块中——仓库cookbook/snippets下的各示例目录(如 dockerfile 构建 Go 模块)都带有dagger.json与入口代码,可以作为你创建自己模块时的对照模板。
编写模块函数:DockerBuild + 仓库凭据 + Publish
先给出 cookbook 中两个被分别文档化的模式,再给出本文使用的组合写法。
模式一,从 Dockerfile 构建并发布的函数:
// Build and publish image from existing Dockerfile func (m *MyModule) Build( ctx context.Context, // location of directory containing Dockerfile src *dagger.Directory, ) (string, error) { ref, err := src. DockerBuild(). // build from Dockerfile Publish(ctx, "ttl.sh/hello-dagger") if err != nil { return "", err } return ref, nil }模式二,发布到私有 registry 的函数,关键在于WithRegistryAuth(registry, username, password),其中password是*dagger.Secret类型:
// Publish a container image to a private registry func (m *MyModule) Publish( ctx context.Context, // Registry address registry string, // Registry username username string, // Registry password password *dagger.Secret, ) (string, error) { return dag.Container(). From("nginx:1.23-alpine"). WithNewFile( "/usr/share/nginx/html/index.html", "Hello from Dagger!", dagger.ContainerWithNewFileOpts{Permissions: 0o400}, ). WithRegistryAuth(registry, username, password). Publish(ctx, fmt.Sprintf("%s/%s/my-nginx", registry, username)) }本文的目标场景是把两者串起来:镜像来自 Dockerfile(而不是From基础镜像 + 文件操作),发布目标是需要鉴权的私有仓库。组合后的完整函数如下:
package main import ( "context" "fmt" "dagger/my-module/internal/dagger" ) type MyModule struct{} // 从 Dockerfile 构建镜像并发布到私有镜像仓库 func (m *MyModule) Build( ctx context.Context, // location of directory containing Dockerfile src *dagger.Directory, // Registry address registry string, // Registry username username string, // Registry password password *dagger.Secret, ) (string, error) { return src.DockerBuild(). // build from Dockerfile WithRegistryAuth(registry, username, password). Publish(ctx, fmt.Sprintf("%s/%s/app:latest", registry, username)) }其中每个环节都来自上面两个文档化模式:DockerBuild()作用于传入的目录(该目录内必须有 Dockerfile),WithRegistryAuth在发布前注入仓库凭据,Publish把镜像推到目标引用并返回该引用字符串。末尾的app:latest是示例镜像名与标签,请替换为你自己的镜像命名;registry/username前缀的引用格式沿用文档示例fmt.Sprintf("%s/%s/my-nginx", registry, username)的写法。
运行发布命令
文档中的示例把仓库密码放在环境变量PASSWORD中,并通过env://PASSWORD传入,Dagger 会将其作为Secret读取。运行前需要先设置该环境变量,例如 ghcr.io 场景下放 GitHub personal access token(文档原文:the GitHub personal access token set in thePASSWORDenvironment variable)。
对组合函数,使用 Dagger CLI 的命名参数形式调用:
dagger call build \ --src="https://github.com/dockersamples/python-flask-redis" \ --registry=ghcr.io \ --username=user \ --password=env://PASSWORD--src的值、ghcr.io和user均取自文档示例,请替换为你自己的源码位置与仓库账号;--src指向包含 Dockerfile 的目录。参数名--registry、--username、--password沿用文档中 私有 registry 发布示例 的 CLI 形式。
文档中两个单一模式的原始示例命令(示例结果)供对照:
# 从 Dockerfile 构建并发布(文档示例,目标为 ttl.sh) dagger -c 'build https://github.com/dockersamples/python-flask-redis' # 携带凭据发布到 ghcr.io(文档示例) dagger -c 'publish ghcr.io user env://PASSWORD'确认发布结果
两个文档化函数的返回值都是发布后的镜像引用字符串:构建函数中ref, err := src.DockerBuild()...Publish(ctx, ...),成功后返回ref;发布函数直接return ...Publish(ctx, ...)得到的字符串。因此判断成功的方式就是:dagger call执行完毕且输出为预期的镜像引用(例如按上面组合函数构造的ghcr.io/user/app:latest这类引用)。如果构建或推送失败,函数返回err,命令不会输出镜像引用。
可选分支:Dockerfile 与源码不在同一目录
当 Dockerfile 位于另一处(例如独立的 dockerfiles 仓库)时,文档提供了双参数形式:函数额外接收dockerfile *dagger.File,先WithFile("/src/custom.Dockerfile", dockerfile)把它放进构建上下文,再用DockerBuild(dagger.DirectoryDockerBuildOpts{Dockerfile: "custom.Dockerfile"})指定文件名。对应调用示例(文档原文):
dagger -c 'build https://github.com/dockersamples/python-flask-redis https://github.com/vimagick/dockerfiles#master:registry-cli/Dockerfile'同样的凭据参数可以叠加在这一分支上。另外,如果需要一次推送多个 tag 到私有 registry,参见 multi-tag 发布示例。
适用边界与参考
- 文档中 Dockerfile 构建示例的默认发布目标是
ttl.sh/hello-dagger,那是一个演示用的临时目标;面向私有仓库时必须加上WithRegistryAuth并替换发布引用,这正是本文组合函数的做法。 - 密码参数在 API 中是
*dagger.Secret类型(Go),不要以明文参数直接传递;CLI 层通过env://PASSWORD从环境变量读取。 - 主要文档入口:Builds cookbook、Container Images cookbook。
- 各语言完整示例:Go dockerfile 构建、Python dockerfile 构建、Go 私有仓库发布、Python 私有仓库发布。
【免费下载链接】daggerAutomation engine to build, test and ship any codebase. Runs locally, in CI, or directly in the cloud项目地址: https://gitcode.com/GitHub_Trending/da/dagger
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考