Dagger TypeScript SDK 之 DirectoryDockerBuildOpts:从目录构建 Docker 镜像的完整参数指南
发布时间:2026/9/17 4:39:51 作者:尧图编辑部 阅读量:1,286

Dagger TypeScript SDK 之 DirectoryDockerBuildOpts从目录构建 Docker 镜像的完整参数指南【免费下载链接】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导读本文围绕 Dagger TypeScript SDK 中Directory.dockerBuild()方法的可选参数类型DirectoryDockerBuildOpts定义于 DirectoryDockerBuildOpts.md展开讲解如何基于一个Directory目录对象、通过 Dockerfile 兼容方式构建出Container容器。读完本文你将掌握dockerBuild的全部 7 个可选参数的语义、默认值与底层实现原理能够用buildArgs、target、platform、secrets、ssh、noInit和dockerfile组合出实际可运行的构建流水线并了解 Dagger 引擎在源码层面对这些参数的处理细节。DirectoryDockerBuildOpts是 Dagger TypeScript 自动生成 APIapi/client.gen中的一个Type Alias类型别名类型为object全部字段均为可选optional用于向dockerBuild查询传递配置。它在运行时会被序列化为 GraphQL 调用参数最终由 Dagger 引擎的 core/schema/directory.go 中的dockerBuild解析器消费。一、类型定义与参数总览在 sdk/typescript/src/api/client.gen.ts 中该类型被生成为export type DirectoryDockerBuildOpts { /** * Path to the Dockerfile to use (e.g., frontend.Dockerfile). */ dockerfile?: string /** * The platform to build. */ platform?: Platform /** * Build arguments to use in the build. */ buildArgs?: BuildArg[] /** * Target build stage to build. */ target?: string /** * Secrets to pass to the build. * * They will be mounted at /run/secrets/[secret-name]. */ secrets?: Secret[] /** * If set, skip the automatic init process injected into containers created by RUN statements. * * This should only be used if the user requires that their exec processes be the pid 1 process in the container. Otherwise it may result in unexpected behavior. */ noInit?: boolean /** * A socket to use for SSH authentication during the build * * (e.g., for Dockerfile RUN --mounttypessh instructions). * * Typically obtained via host.unixSocket() pointing to the SSH_AUTH_SOCK. */ ssh?: Socket }调用方式为directory.dockerBuild(opts?: DirectoryDockerBuildOpts): Container对应实现见 client.gen.tsSDK 会把整个 opts 对象展开后作为dockerBuild的 GraphQL 参数提交dockerBuild (opts?: DirectoryDockerBuildOpts): Container { const ctx this._ctx.select(dockerBuild, { ...opts }) return new Container(ctx) }参数类型必填默认行为作用dockerfilestring否Dockerfile指定要使用的 Dockerfile 路径如frontend.DockerfileplatformPlatform否引擎默认平台指定构建目标平台buildArgsBuildArg[]否空数组传入构建参数对应ARGtargetstring否空字符串指定要构建的目标构建阶段对应--targetsecretsSecret[]否空数组构建期 Secret挂载到/run/secrets/[secret-name]noInitboolean否false是否跳过 RUN 语句自动注入的 init 进程sshSocket否无构建期 SSH 认证 socket对应RUN --mounttypessh这些默认值并非凭空而来——在引擎侧的 dirDockerBuildArgs 结构体中有明确的default标记与之对应type dirDockerBuildArgs struct { Platform dagql.Optional[core.Platform] Dockerfile string default:Dockerfile Target string default: BuildArgs []dagql.InputObject[core.BuildArg] default:[] Secrets []core.SecretID default:[] NoInit bool default:false SSH dagql.Optional[core.SocketID] }二、dockerfile选择自定义 Dockerfile 路径签名dockerfile?: string指定相对于构建上下文目录即调用dockerBuild的那个Directory的 Dockerfile 路径。默认值为Dockerfile。原文档给出的典型场景是构建上下文根目录下同时存在多个 Dockerfile 时用该参数挑选其中一个例如frontend.Dockerfile。底层实现dockerignore 的解析有趣的是dockerfile参数不仅决定了使用哪个 Dockerfile还参与了.dockerignore的选择逻辑。引擎侧的applyDockerIgnore见 core/schema/directory.go遵循 Docker 官方的上下文规则filename-and-location优先读取dockerfile.dockerignore例如传入custom.Dockerfile时读取custom.Dockerfile.dockerignore若该文件不存在或为空则回退读取默认的.dockerignore若仍无排除规则直接使用原目录作为构建上下文否则对目录执行filterexclude操作得到剔除无关文件后的精简构建上下文。这一机制意味着使用自定义 Dockerfile 时你既可以配套写一份custom.Dockerfile.dockerignore精确控制该次构建的上下文也可以复用全局.dockerignore。实战示例构建上下文与 Dockerfile 分离当 Dockerfile 不在当前工作目录时可先构造一个包含 Dockerfile 的上下文目录再构建。仓库中的官方示例 dockerfile-context/typescript/index.ts 展示了这种做法import { dag, Directory, File, object, func } from dagger.io/dagger object() class MyModule { func() async build(src: Directory, dockerfile: File): Promisestring { // 把 Dockerfile 加入构建上下文 const workspace await dag .container() .withDirectory(/src, src) .withWorkdir(/src) .withFile(/src/custom.Dockerfile, dockerfile) .directory(/src) // 构建并发布到镜像仓库 const ref await workspace .dockerBuild({ dockerfile: custom.Dockerfile }) .publish(ttl.sh/hello-dagger) return ref } }三、buildArgs向构建传入 ARG 参数签名buildArgs?: BuildArg[]对应 Docker 的--build-arg用于向 Dockerfile 中的ARG注入构建期变量。元素类型BuildArg同样是对象类型定义于 client.gen.tsexport type BuildArg { /** The build argument name. */ name: string /** The build argument value. */ value: string }使用示例const ctr await src.dockerBuild({ buildArgs: [ { name: NODE_VERSION, value: 20 }, { name: ENV, value: production }, ], })引擎侧这些参数会被collectInputsSlice(args.BuildArgs)收集后传给ctr.Build(...)见 core/schema/directory.go最终进入 BuildKit 的构建参数解析。注意BuildArg的name与value均为必填字符串没有默认值传入时二者缺一不可。四、target选择多阶段构建的目标阶段签名target?: string对应 Docker 的--target用于多阶段构建multi-stage build中只构建到某个指定阶段为止。默认值为空字符串表示构建 Dockerfile 的最终阶段。// 仅构建到名为 builder 的阶段 const ctr await src.dockerBuild({ target: builder })在引擎侧Target被原样透传给ctr.Buildcore/schema/directory.go。典型用途包括只想拿到编译产物阶段如golang:builder阶段用于导出二进制而跳过最终运行时镜像的构建从而显著减少构建与缓存开销。五、platform指定构建目标平台签名platform?: Platform指定构建目标平台如linux/amd64、linux/arm64对应 Docker 的--platform。Platform类型定义于 Platform.md。默认值动态注入引擎默认平台如果不传该参数Dagger 会在查询执行期动态注入当前引擎的默认平台。这是通过NodeFuncWithDynamicInputs与dockerBuildDynamicInputs实现的见 core/schema/directory.gofunc (s *directorySchema) dockerBuildDynamicInputs( ctx context.Context, _ dagql.ObjectResult[*core.Directory], args dirDockerBuildArgs, req *dagql.CallRequest, ) error { if args.Platform.Valid { return nil } platform, err : currentEngineDefaultPlatform(ctx) if err ! nil { return err } return req.SetArgInput(ctx, platform, platform, false) }即只有在platform未显式提供时Dagger 才会调用currentEngineDefaultPlatform取回引擎默认平台并写入调用参数一旦你显式传入platform该逻辑直接跳过。而在解析器dockerBuild中core/schema/directory.go传入的平台会覆盖查询默认平台platform : query.Platform() if args.Platform.Valid { platform args.Platform.Value }新容器即按该平台创建core.NewContainer(platform)。这使 Dagger 天然支持在任意宿主机上交叉构建多平台镜像。六、secrets构建期 Secret 与 /run/secrets 挂载签名secrets?: Secret[]向构建传入一组Secret对象。它们会被挂载到容器内的/run/secrets/[secret-name]供 Dockerfile 中以RUN --mounttypesecret,idname方式使用。实战示例把 Secret 安全传给 Dockerfile官方示例 secret-dockerfile/typescript/index.ts 展示了完整链路import { dag, object, func, Secret } from dagger.io/dagger object() class MyModule { func() async build(source: Directory, secret: Secret): PromiseContainer { // 保证 Dagger Secret 的 name 与 Dockerfile 中 secret mount 的 id 一致 const buildSecret dag.setSecret(gh-secret, await secret.plaintext()) return source.dockerBuild({ secrets: [buildSecret] }) } }配套 Dockerfile 中可这样消费RUN --mounttypesecret,idgh-secret \ export GH_TOKEN$(cat /run/secrets/gh-secret) ...实现细节按 ID 加载 Secret引擎侧secrets参数的类型是[]core.SecretID在解析器中被批量加载core/schema/directory.gosecrets, err : dagql.LoadIDResults(ctx, srv, args.Secrets)也就是说SDK 层的Secret对象会被解析为对应的 Secret ID再由引擎统一Load得到真实的 Secret 内容后注入 BuildKit 构建流程。Secret 名称与挂载 id 的对应关系是约定式的——正如示例注释所强调的dag.setSecret(name, ...)中的name必须与 Dockerfile 中--mounttypesecret,idname的id保持一致才能正确读到值。七、ssh构建期 SSH 认证 socket签名ssh?: Socket提供一个Socket用于构建期间的 SSH 认证典型场景是 Dockerfile 中的RUN --mounttypessh指令例如从私有 Git 仓库拉取依赖。原文档特别说明该 socket 通常通过host.unixSocket()指向宿主机的SSH_AUTH_SOCK环境变量获得从而把宿主机上已解锁的 SSH agent 会话带入构建过程无需在镜像内复制私钥。const sshAgent await dag .host() .unixSocket(/run/host-services/ssh-auth.sock) // 或直接指向 SSH_AUTH_SOCK const ctr await src.dockerBuild({ ssh: sshAgent, })配合 DockerfileRUN --mounttypessh git clone gitgithub.com:my-org/private-repo.git实现细节socket 的显式加载与校验引擎侧对ssh的处理值得注意core/schema/directory.go它不会静默忽略无效 socket而是先Load再显式校验加载结果是否为 nil失败即返回错误var sshSocket dagql.ObjectResult[*core.Socket] if args.SSH.Valid { sshSocket, err args.SSH.Value.Load(ctx, srv) if err ! nil { return nil, fmt.Errorf(failed to load SSH socket: %w, err) } if sshSocket.Self() nil { return nil, fmt.Errorf(failed to load SSH socket: nil socket) } }如果传入的 socket 未正确绑定到真实的 SSH agent构建会在这一环节直接报错便于快速定位问题而不是到 RUN 阶段才失败。八、noInit控制自动注入的 init 进程签名noInit?: booleanDagger 引擎默认会在 DockerfileRUN语句创建的容器中自动注入一个 init 进程用于信号转发与子进程回收避免出现僵尸进程等容器化常见问题。设置noInit: true可以跳过该注入。原文档给出了明确的使用警告仅在确实需要让执行进程成为容器内pid 1进程时才应开启否则可能导致意外行为例如信号无法正确传递到主进程、子进程残留。// 仅在确有必要时开启 const ctr await src.dockerBuild({ noInit: true })从 dirDockerBuildArgs 可见其默认值为false即默认始终注入 init 进程。因此绝大多数构建场景都不需要设置该参数只有对进程管理有特殊要求的容器如某些系统级或自定义 runtime 的镜像才需要考虑。九、完整示例组合多个参数的一次真实构建结合以上所有参数一个覆盖多阶段、交叉平台、构建参数与 Secret 的完整 TypeScript 模块如下综合自 dockerfile/typescript/index.ts 及本文各参数的用法import { dag, Directory, Secret, object, func } from dagger.io/dagger object() class MyModule { /** * 基于已有 Dockerfile 构建并发布多平台镜像 */ func() async build( src: Directory, npmToken: Secret, ): Promisestring { const ctr src.dockerBuild({ dockerfile: frontend.Dockerfile, // 自定义 Dockerfile target: production, // 多阶段构建目标阶段 platform: linux/amd64, // 目标平台 buildArgs: [ { name: NODE_VERSION, value: 20 }, ], secrets: [dag.setSecret(npm-token, await npmToken.plaintext())], // noInit 保持默认 false交给引擎自动注入 init 进程 }) return await ctr.publish(ttl.sh/my-app) } }十、引擎侧整体执行链路DirectoryDockerBuildOpts中的每一个参数最终都汇聚到引擎侧同名的解析器。完整的执行链路基于 core/schema/directory.go如下GraphQL 路由dockerBuild以dagql.NodeFuncWithDynamicInputs注册到 Directory 类型上directory.go并标记为Dockerfile 兼容入口——其 Doc 明确指出“仅为 Dockerfile 兼容而保留原生Container类型功能完备、支持全部 Dockerfile 特性”平台解析未显式传platform时由dockerBuildDynamicInputs注入引擎默认平台上下文裁剪applyDockerIgnore依据dockerfile.dockerignore→.dockerignore的优先级过滤构建上下文输入加载secrets批量LoadIDResults、ssh显式加载并校验非空委托构建ctr.Build(ctx, parent, buildctxDirID, dockerfile, buildArgs, target, secrets, noInit, sshSocket)最终把全部参数转交给 BuildKit 完成镜像构建。通过这条链路可以看到DirectoryDockerBuildOpts并非一个简单的“传参对象”而是 Dagger 将 Docker 构建语义完整映射到图查询执行引擎的桥接层——它保证了dockerBuild既能兼容存量 Dockerfile 工作流又能无缝接入 Dagger 的缓存、平台与 Secret 体系。相关文档与源码索引类型别名定义DirectoryDockerBuildOpts.md所属 API 模块api/client.gen README宿主方法Directory.dockerBuild()classes/Directory.md关联类型BuildArg.md、Platform.md、Secret 类、Socket 类TypeScript 生成代码sdk/typescript/src/api/client.gen.ts引擎实现core/schema/directory.go官方示例dockerfile 构建、自定义 Dockerfile 上下文、Dockerfile 使用 Secret【免费下载链接】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),仅供参考