
Dagger TypeScript SDK 中 ContainerPublishOpts 详解发布镜像时的压缩、媒体类型与多平台参数【免费下载链接】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 SDKdagger.io/dagger中Container#publish方法的可选参数对象ContainerPublishOpts展开完整覆盖forcedCompression、mediaTypes、platformVariants三个属性的语义、默认行为与取值范围并结合开源仓库中的核心引擎实现源码core/container.go与官方示例multi-arch TypeScript 示例讲清这些参数在底层如何生效。读完后你可以掌握在 DAG/CI 中发布单平台与多平台镜像时的全部可选配置包括层压缩算法选择、OCI/Docker 媒体类型切换以及跨架构镜像的正确拼装方式。原始 API 参考文档位于 ContainerPublishOpts.md类型为/** * ContainerPublishOpts object */即它是publish方法上唯一的可选参数对象所有属性均可省略、全部使用默认值。三个可选属性总览ContainerPublishOpts只包含三个可选属性对应文档中列出的全部字段属性类型是否必填作用forcedCompression?ImageLayerCompression否强制已发布镜像的每一层使用指定压缩算法mediaTypes?ImageMediaTypes否指定发布镜像层所使用的媒体类型OCI 或 DockerplatformVariants?Container[]否其他平台对应容器的标识符用于构建多平台镜像以下逐条展开。forcedCompression强制统一镜像层的压缩算法文档原文语义为Force each layer of the published image to use the specified compression algorithm.强制已发布镜像的每一层使用指定的压缩算法默认行为不设置该参数时文档对该参数的默认行为有明确的两句说明是使用前必须理解的关键点命中引擎缓存时直接复用已压缩的 blob如果未设置forcedCompression而镜像某一层在引擎缓存中已经存在压缩过的 blob则会直接复用该缓存对象——这意味着不同层可能最终采用不同的压缩算法混用缓存未命中时回退到 Gzip如果未设置且某一层在引擎缓存中没有已压缩的 blob则默认使用Gzip压缩。因此默认策略本质上是“缓存优先 Gzip 兜底”而不是每次发布都统一重压。可选取值ImageLayerCompression是一个字符串枚举定义见 ImageLayerCompression.md包含五个成员其中两个是同一值的别名拼写枚举成员字符串值说明EstargzEStarGZeStargzOCI 兼容的 gzip 格式支持按需拉取EstarGzEStarGZ同上命名别名GzipGzip标准 gzip 压缩UncompressedUncompressed不压缩注意传输/存储体积ZstdZstdZstandard 压缩mediaTypes选择 OCI 或 Docker 媒体类型文档语义为Use the specified media types for the published images layers.为已发布镜像的层使用指定的媒体类型Defaults to OCI, which is compatible with most recent registries, but Docker may be needed for older registries without OCI support.默认使用 OCI与大多数现代 registry 兼容但对接不支持 OCI 的旧 registry 时可能需要 Docker对应的ImageMediaTypes枚举共 4 个成员实际上是两组别名枚举成员字符串值说明DockerDockerMediaTypesDocker 经典媒体类型DockerMediaTypesDockerMediaTypes同上命名别名OciOCIMediaTypesOCI 媒体类型默认OcimediaTypesOCIMediaTypes同上命名别名从命名可以推断两种拼写只是 TypeScript 代码风格上的等价别名PascalCase 与全大写缩写运行时值是相同的字符串因此任选其一即可。适用前提是目标 registry 的兼容能力默认 OCI 覆盖绝大多数现代 registry只有当目标端是老式 Docker registry 且其不接受 OCI manifest 时才需要显式传mediaTypes: ImageMediaTypes.Docker。platformVariants发布多平台镜像文档语义为Identifiers for other platform specific containers. Used for multi-platform image.其他平台对应容器的标识符用于多平台镜像platformVariants接收一个Container数组。它的语义不是“把多个容器的文件系统合并”而是“每个容器对应一个目标平台的构建产物”发布时引擎会为它们生成一个 manifest index让同一 tag 按客户端架构解析到不同平台的 manifest。引擎侧实现印证从源码结构看publish在引擎侧的入口是 core/container.go 中的Container.Publish方法其签名与ContainerPublishOpts的三个属性一一对应func (container *Container) Publish( ctx context.Context, ref string, platformVariants []*Container, forcedCompression ImageLayerCompression, mediaTypes ImageMediaTypes, registryServices ServiceBindings, registryTransport serverresolver.RegistryTransport, ) (string, error) { variants : filterEmptyContainers(append([]*Container{container}, platformVariants...)) inputByPlatform, err : getVariantRefs(ctx, variants) ... resp, err : bk.PublishContainerImage(ctx, inputByPlatform, ref, useOCIMediaTypes(mediaTypes), string(forcedCompression), network, registryTransport) ... withDig, err : reference.WithDigest(refName, resp.RootDesc.Digest) return withDig.String(), nil }这段实现印证了几个文档层面的行为细节当前容器与 variants 合并后按平台分组实现先把主容器container与platformVariants拼成一个列表经filterEmptyContainers过滤空容器后再由getVariantRefs按平台整理成inputByPlatform。也就是说platformVariants里每个容器的platform属性决定了它在 manifest index 中的平台槽位mediaTypes 与压缩参数直接透传给引擎useOCIMediaTypes(mediaTypes)与string(forcedCompression)作为参数交给bk.PublishContainerImage说明压缩算法与媒体类型选择是在引擎发布路径上生效的而非在客户端 SDK 侧做转换返回值是带 digest 的完整引用发布完成后实现会解析resp.RootDesc.Digest并返回形如repo:tagsha256:...的规范化引用。这正是文档中publish返回镜像 digestdigest-pinned ref的来源可放心用于后续构建的缓存锚点。TypeScript 侧的类型定义位于 sdk/typescript/src/api/client.gen.tsContainerPublishOpts与ImageLayerCompression、ImageMediaTypes均在其中生成与本文档页一一对应。实战示例完整的多平台发布流程Dagger 官方 cookbook 的 multi-arch 示例docs/versioned_docs/version-0.20/cookbook/snippets/builds/multi-arch/typescript/index.ts完整展示了platformVariants的用法核心逻辑如下import { dag, Container, Directory, Platform, object, func, } from dagger.io/dagger object() class MyModule { /** * Build and publish multi-platform image * param src source code location */ func() async build(src: Directory): Promisestring { // platforms to build for and push in a multi-platform image const platforms: Platform[] [ linux/amd64 as Platform, // a.k.a. x86_64 linux/arm64 as Platform, // a.k.a. aarch64 linux/s390x as Platform, // a.k.a. IBM S/390 ] // container registry for multi-platform image const imageRepo ttl.sh/myapp:latest const platformVariants: ArrayContainer [] for (const platform of platforms) { const ctr dag .container({ platform: platform }) .from(golang:1.21-alpine) // mount source .withDirectory(/src, src) // mount empty dir where built binary will live .withDirectory(/output, dag.directory()) // ensure binary will be statically linked and thus executable // in the final image .withEnvVariable(CGO_ENABLED, 0) .withWorkdir(/src) .withExec([go, build, -o, /output/hello]) // select output directory const outputDir ctr.directory(/output) // wrap output directory in a new empty container marked // with the same platform const binaryCtr await dag .container({ platform: platform }) .withRootfs(outputDir) platformVariants.push(binaryCtr) } // publish to registry const imageDigest await dag .container() .publish(imageRepo, { platformVariants: platformVariants }) return imageDigest } }这个示例有几个值得注意的工程细节直接体现了ContainerPublishOpts的正确使用姿势每个 variant 必须标记正确的 platform循环内dag.container({ platform: platform })两次编译阶段与最终镜像阶段都显式指定了平台否则引擎无法把容器归属到 manifest index 中对应的平台槽位withRootfs构造最小镜像最终发布用的binaryCtr是用withRootfs(outputDir)把静态二进制包装进一个“空容器”里得到的避免把 golang 基础镜像整体打进最终产物调用形式publish(imageRepo, { platformVariants })中主容器是一个占位的空容器真实的多平台内容由platformVariants数组提供返回值imageDigest即 digest-pinned 的镜像引用可直接回传给调用方做记录或下游消费。在此示例基础上若需要额外控制压缩与媒体类型写法为await dag .container() .publish(imageRepo, { platformVariants, forcedCompression: ImageLayerCompression.Zstd, // 强制所有层统一使用 Zstd mediaTypes: ImageMediaTypes.Oci, // 默认即为 OCI可省略 })需要说明的前提显式传入forcedCompression会放弃“缓存压缩 blob 复用”的默认路径每一层都按指定算法重新计算/封装适合对产物一致性有要求的发布场景而默认路径不传则最大化利用引擎缓存但接受层间压缩算法可能不一致的结果。小结与使用建议ContainerPublishOpts是 Dagger TypeScript SDK 中Container#publish的完整可选配置面三个属性各自解决一类发布问题不设置任何参数发布默认单平台或按platformVariants多平台镜像层压缩走“缓存复用 Gzip 兜底”媒体类型为 OCI——对绝大多数现代 registry 直接可用forcedCompression当发布产物需要统一压缩格式如统一Zstd、Uncompressed或 eStargz时显式指定注意它会使每层都按该算法处理mediaTypes仅当目标 registry 是不支持 OCI 的旧版 Docker registry 时才需要切到DockerplatformVariants构建多平台镜像的核心入口配合每个 variant 容器的platform属性使用发布后返回带 digest 的引用可用于审计与缓存锚定。以上行为均以当前仓库的 API 参考文档、core/container.go 中的Publish实现与官方 cookbook 示例为准若你升级 SDK 版本建议重新核对对应版本的枚举成员与默认值文档。【免费下载链接】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),仅供参考