
Dagger TypeScript SDK 中 ContainerWithMountedSecretOpts 挂载密钥选项详解【免费下载链接】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 中Secret用于安全地承载口令、令牌、私钥等敏感数据避免其直接出现在容器镜像层或日志中。withMountedSecret是Container上的核心方法负责把这样一个密钥以文件的形式挂载进容器例如/run/secrets/foo。本文围绕dagger.io/dagger0.20 版本TypeScript SDK 中的类型别名ContainerWithMountedSecretOpts逐一讲解其owner、mode、expand三个可选配置项的含义、底层实现原理与完整实战用法帮助你精确控制密钥挂载后的文件权限、属主和路径解析行为。一、类型别名概览ContainerWithMountedSecretOpts在 TypeScript SDK 中定义于 sdk/typescript/src/api/client.gen.ts属于client.gen模块是调用withMountedSecret方法时传入的可选参数对象类型export type ContainerWithMountedSecretOpts { owner?: string mode?: number expand?: boolean }三个字段全部为可选optional。它在 client.gen.ts 中与withMountedSecret方法签名配合使用withMountedSecret ( path: string, source: Secret, opts?: ContainerWithMountedSecretOpts, ): Container { const ctx this._ctx.select(withMountedSecret, { path, source, ...opts }) return new Container(ctx) }其中path是密钥挂载的目标路径如/run/secrets/tokensource是通过setSecret或host().setSecretFile创建的Secret对象opts则是本文的主角。二、字段详解1.owner?: string — 挂载密钥的文件属主设置挂载密钥的user:group。用户与组既可以是 ID如1000:1000也可以是名称如foo:bar。如果省略组则默认与用户相同。取值范围uid、uid:gid、user、user:group四种形式均可例如1000、1000:1000、root、root:root。默认行为不传owner时不改变挂载文件的属主沿用容器默认用户通常是 root。特性这是让mode生效的前置条件见下文。从引擎源码 core/container.go 的ownership函数可以确认其解析逻辑使用strings.Cut(owner, :)切分出uidOrName与可选的gidOrName先用parseUID尝试把值解析为数字 ID失败则视为用户名若传入的是用户名则打开容器内的/etc/passwd通过findUID解析出 UID若传入的是组名则打开容器内的/etc/group通过findGID解析出 GID若省略了组则令gid uid与文档描述“组默认为用户”完全一致。2.mode?: number — 挂载密钥的文件权限赋予挂载密钥的权限例如0600。取值范围标准 Unix 八进制权限位对应的十进制数字常用值为0o400仅读、0o600属主读写、0o644、0o400等。TypeScript 中可直接写0o600或十进制384。关键限制该选项只有在设置了owner时才生效。原因在于只有在确定了属主之后引擎才能正确计算并应用权限位对应的 ACL若未指定属主mode会被忽略。底层实现中mode以fs.FileMode类型传入引擎见 core/container.go 的WithMountedSecret解析出ownership后与挂载路径一起追加到container.Secrets列表最终在生成容器执行计划时应用为挂载文件的权限与属主。3.expand?: boolean — 挂载路径中的环境变量展开根据容器中当前定义的环境变量替换path值中的${VAR}或$VAR例如/$VAR/foo。取值范围true/false或省略。作用当密钥挂载路径中包含环境变量占位符时将其展开为容器内对应环境变量的实际值。例如容器通过withEnvVariable(SECRETS_DIR, /run/secrets)定义了环境变量挂载路径写/$SECRETS_DIR/token设置expand: true后实际挂载到/run/secrets/token。默认行为不传时不做展开路径按字面值处理。三、GraphQL Schema 中的对应关系ContainerWithMountedSecretOpts并非凭空定义它直接对应该功能在 GraphQL 层withMountedSecret字段的入参。在 core/schema/container.go 中withMountedSecret被声明为Container的节点函数其入参文档与 TypeScript 类型一一对应path密钥文件位置如/tmp/secret.txtsource要挂载的密钥标识owneruser:group支持 ID 或名称省略组时默认同用户mode挂载密钥的权限如 0600需要设置owner才生效expand是否按容器环境变量展开路径中的${VAR}/$VAR。TypeScript SDK 由 GraphQL schema 代码生成而来生成入口见 cmd/codegen/generate_client.go因此 sdk/typescript/src/api/client.gen.ts 中的类型注释与 schema 文档保持一致——这也意味着你查阅文档如本仓库 docs/versioned_docs/version-0.20/reference/typescript/api/client.gen/type-aliases/ContainerWithMountedSecretOpts.md即可获得与代码一致的权威说明。四、完整实战示例下面是一个在 TypeScript SDK 中使用全部三个选项的完整示例把主机的 SSH 私钥作为Secret挂载到容器中指定属主与权限并对挂载路径做环境变量展开。import { Client, connect } from dagger.io/dagger; connect(async (client: Client) { // 1. 读取宿主机 SSH 私钥并包装为 Secret const sshKey client.host() .setSecretFile(ssh-key, client.host().file(/root/.ssh/id_ed25519)); // 2. 构造容器定义环境变量并挂载密钥 const container client .container() .from(alpine:latest) .withEnvVariable(SECRETS_DIR, /run/secrets) .withMountedSecret(/$SECRETS_DIR/ssh_key, sshKey, { owner: 1000:1000, // 属主UID 1000 / GID 1000 mode: 0o600, // 权限仅属主可读写依赖 owner 生效 expand: true, // 展开路径中的 $SECRETS_DIR }); // 3. 在容器内验证挂载结果 const out await container .withExec([sh, -c, ls -l /run/secrets test \$(stat -c %a %u %g /run/secrets/ssh_key)\ 600 1000 1000]) .stdout(); console.log(out); });执行后/run/secrets/ssh_key将以-rw-------0600、属主1000:1000的形式出现在容器中且路径中的$SECRETS_DIR被正确展开为/run/secrets。最小化用法如果不需要定制属主与权限也可以省略opts直接调用const container client .container() .from(alpine:latest) .withMountedSecret(/run/secrets/token, mySecret);此时挂载文件保持容器默认属主与权限。五、集成测试佐证仓库集成测试 core/integration/secret_test.go 验证了withMountedSecret的核心行为——把密钥以文件形式挂载并能在容器内读取query Test($secret: ID!) { container { from(address: alpine:latest) { withMountedSecret(path: /sekret, source: $secret) { withExec(args: [sh, -c, test \$(cat /sekret)\ \some-content\]) { sync } } } } }该测试通过testutil.Query执行证明密钥内容以文件形式出现在挂载点并可在withExec中读取。同一文件中的TestMountFromFilesecret_test.go还验证了密钥挂载与文件挂载在同一路径时的优先级行为——后挂载的withMountedFile会覆盖同路径的密钥文件。六、使用注意事项mode依赖owner这是最容易踩坑的一点。如果只设置mode而不设置owner权限不会生效。源码文档在 core/schema/container.go 中明确标注了“requires an owner to be set to be active”。owner的解析发生在容器内使用用户名如foo时引擎需要读取容器内的/etc/passwd与/etc/group来解析 UID/GID见 core/container.go。因此该镜像必须包含对应的用户/组记录否则解析会失败。使用数字 ID如1000:1000则无此依赖兼容性更好。expand只作用于挂载路径它仅对path参数做环境变量展开不影响密钥内容本身。展开依据的是挂载操作发生前容器中已定义的环境变量。版本差异ContainerWithMountedSecretOpts在dagger.io/dagger0.20 版本中仅包含owner、mode、expand三个字段。在更新的引擎版本中schema 层还增加了inheritOwner继承容器当前用户选项见 core/schema/container.go 中标注AfterVersion(v1.0.0-0)的参数——若你使用的是 0.20 版本 SDK请以本文三个字段为准。七、小结ContainerWithMountedSecretOpts是控制 Dagger 密钥挂载细节的统一入口字段类型作用默认/限制ownerstring设置挂载文件的user:group支持 ID 或名称省略组时默认同用户不设置则不改属主modenumber设置挂载文件权限如0600必须搭配owner才生效expandboolean按容器环境变量展开路径中的${VAR}/$VAR默认不展开掌握这三个选项你就能在 CI 流水线、云上构建等场景中安全、精细地管理容器内的密钥文件兼顾敏感信息隔离与运行期可读性。更多相关 API 可继续阅读 Container 类型参考 与 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),仅供参考