资讯动态

Docker Compose publish 命令详解:把 Compose 应用发布为 OCI 工件

发布时间:2026/9/6 15:58:50 来源:尧图企业网站定制
Docker Compose publish 命令详解把 Compose 应用发布为 OCI 工件【免费下载链接】composeDefine and run multi-container applications with Docker项目地址: https://gitcode.com/GitHub_Trending/compose/composedocker compose publish用于将一个 Compose 项目整体发布到 OCI 兼容的镜像仓库命令会先对 Compose 文件做安全性预检敏感数据、环境变量、bind mount 声明再把 Compose 文件及其引用的 env 文件、extends 父文件序列化为一组 OCI 层推送到目标仓库生成一个以application/vnd.docker.compose.project为 artifact type 的 OCI 工件。读完本文你将掌握publish各参数的含义与使用前提、工件在仓库中的实际结构以及如何用docker compose -f oci://...拉回并发布pull 后 up这个工件。命令与参数速览命令语法为docker compose publish [OPTIONS] REPOSITORY[:TAG]其中唯一的必填位置参数是目标仓库引用REPOSITORY[:TAG]必须已具备该仓库的推送权限。参数一览来自 docs/reference/compose_publish.md并结合 cmd/compose/publish.go 中的 flag 定义补充参数类型默认值说明--appboolfalse发布完整应用工件额外附带一个引用全部服务镜像的 OCI image index--dry-runboolfalse以 dry run 模式执行只走加载、预检与序列化流程不实际推送--oci-versionstring自动判定指定生成的 OCI image/artifact 规范版本默认自动判定--resolve-image-digestsboolfalse将镜像 tag 解析并固定为 digest--with-envboolfalse将环境变量文件env file内容一并写入发布的 OCI 工件并静默 env 相关确认提示-y,--yesboolfalse对所有确认提示自动回答 yes--insecure-registryboolfalse以明文 HTTP 访问仓库隐藏参数源码注释标明仅供测试用途几个源码中可以确认的实现细节--app打开时runPublish会强制ResolveImageDigests: opts.resolveImageDigests || opts.app见 cmd/compose/publish.go即发布完整应用时镜像引用必然固定为 digest保证 index 指向的镜像不可漂移。-y会把AlwaysOkPrompt()注入服务选项cmd/compose/publish.go跳过 bind mount、敏感数据、env 等全部交互确认源码还保留了对误写的--y的向后兼容与弃用警告cmd/compose/publish.go。--insecure-registry在 flag 注册后被MarkHidden注释明确写着 Shouldonlybe used for testing purpose, we dont want to promote use of insecure registriescmd/compose/publish.go。仓库加载阶段如果检测到本地include指令runPublish会直接报错cannot publish compose file with local includescmd/compose/publish.go因为 include 内容无法作为独立工件分发。发布前预检四类安全检查publish的入口实现是 pkg/compose/publish.go 中的Publish/publish方法。执行推送前preChecks会依次做四件事pkg/compose/publish.go1. 拒绝纯 build 服务checkOnlyBuildSection会检查每个服务如果Image为空且只有build段整个项目无法发布直接报错并列出这些服务名your Compose stack cannot be published as it only contains a build section for service(s): - serviceA原因很直接发布工件只固化image引用消费者无法在无构建上下文的环境中重现构建。2. bind mount 声明确认checkForBindMount收集所有服务的 bind 类型卷pkg/compose/publish.go若存在则交互式提示you are about to publish bind mounts declaration within your OCI artifact. only the bind mount declarations will be added to the OCI artifact (not content) please double check that you are not mounting potential users sensitive directories or data Are you ok to publish these bind mount declarations?注意只发布声明而不发布内容——即消费者的/host/path会映射到他自己的宿主路径提示的目的是防止把含敏感路径的声明扩散出去。3. 敏感数据扫描checkForSensitiveData使用 DefangLabs 的 secret-detector 扫描四类内容pkg/compose/publish.go所有 Compose 文件以未插值的原始 YAML 重新序列化后扫描检查用户真实写入的字面量各服务声明的 env 文件文件缺失时仅required: true才报错可选 env 文件缺失则跳过configs:中由file:定义的资源secrets:中由file:定义的资源。命中后逐项列出类型与键值并要求确认例如 e2e 测试 pkg/e2e/publish_test.go 验证的输出覆盖了 AWS Client ID、AWS Secret Key、Github authentication、JSON Web Token、Private Key 等类别。拒绝输入n会使整个发布以operation cancelled退出码 130终止--yes则全部自动确认。4. 环境变量与 config content 泄漏检查checkEnvironmentVariables针对即将被序列化进工件的每一个 Compose 文件含 extends 父文件做更细粒度的 env 检查pkg/compose/publish.goenv_file 声明任何服务声明了env_file都会列出service X: env_file declared因为文件路径本身即本地环境信息可疑键名字面量用关键字检测器password、secret、token、api_key 等键名扫描environment的字面值如MYSQL_ROOT_PASSWORD: toto会被标记为service db: literal value for MYSQL_ROOT_PASSWORD插值安全${DB_PASSWORD}、$API_KEY这类插值在工件中保持符号形态、不泄漏解析后的值因此不会触发提示pkg/compose/publish.go 的注释与 pkg/compose/publish_test.go 中 interpolated values are silent 用例均确认了这一点$$转义字面$会被还原判断pa$$word这类仍按字面量告警字面config.content内联 config 内容若为字面量非插值模板单独弹出一个确认框该检查与--with-env解耦——--with-env只控制环境变量相关提示。提示文案中还写明了出口Use --with-env to silence this prompt and always publish env declarations.这些行为由 pkg/e2e/publish_test.go 的场景测试逐一固化。工件内容层是如何生成的预检通过后publish会调用非导出的s.push而非公开Push先把项目引用的镜像推送到仓库IgnoreFailures: true, ImageMandatory: truepkg/compose/publish.go——即每个服务声明的 image 必须可推送成功这是ImageMandatory的语义。随后createLayers构建工件的层pkg/compose/publish.goCompose 文件层每个顶层 Compose 文件经过processFile处理——以原始环境重新加载后做两项改写env_file路径被替换为路径字符串 SHA-256 哈希命名的hash.env占位符真实文件仅在--with-env时作为独立层上传media typeapplication/vnd.docker.compose.envfile。文件缺失但required: false时占位符仍写入保证工件不泄漏本地路径且行为一致只是不注册上传这一点由 pkg/compose/publish_test.go 的Test_processFile_optional_env_file_missing验证extends.file同样被改写为hash.yaml占位符父文件作为带com.docker.compose.extends: true注解的层递归上传pkg/compose/publish.go。因此工件中不存在发布者的绝对/相对路径。env 文件层仅--with-env由envFileLayers把envFilesmap 中登记的文件逐一打包pkg/compose/publish.go。digest override 层仅--resolve-image-digests或--appgenerateImageDigestsOverride通过ImageDigestResolver对服务镜像、pre_starthook 镜像、type: image卷源镜像逐一DistributionInspect生成一份只含image: reposha256:...的 override YAMLpkg/compose/publish.go覆盖范围由 pkg/compose/publish_test.go 的 mock 测试确认。单元测试Test_createLayerspkg/compose/publish_test.go展示了改写后的实际形态extends.file变为f8f9ede3...d390c.yamlenv_file变为5efca9cd...451af3.env且各层带有com.docker.compose.file/com.docker.compose.envfile注解。测试数据可参考 pkg/compose/testdata/publish/compose.yaml。OCI 工件结构与版本兼容层与清单的推送在 internal/oci/push.go 中完成。工件的关键常量常量值用途ComposeProjectArtifactTypeapplication/vnd.docker.compose.projectOCI 1.1 manifest 的artifactType字段ComposeYAMLMediaTypeapplication/vnd.docker.compose.fileyamlCompose 文件层的 media typeComposeEmptyConfigMediaTypeapplication/vnd.docker.compose.config.empty.v1jsonOCI 1.0 模式下的空 config media typeComposeEnvFileMediaTypeapplication/vnd.docker.compose.envfileenv 文件层的 media typePushManifest的版本策略internal/oci/push.go未指定--oci-version时先尝试按OCI 1.1生成清单带artifactType、空 JSON config若仓库返回非认证类的 4xx说明仓库不支持 1.1 特性自动回退为 OCI 1.0形态artifactType省略config 使用ComposeEmptyConfigMediaType让依赖 config.mediaType 识别工件的旧工具链仍能认出这是 Compose 工件internal/oci/push.go--oci-version显式取值1.0/1.1pkg/api/api.go时跳过探测。API 注释还说明Compose 目前会基于域名对 ECR 仓库自动使用 OCI 1.0 模式pkg/api/api.go。--app可整体拉取的应用 index--app会额外推送一个 image indexpkg/compose/publish.go对每个服务的 image 执行 registry-to-registry 复制引用oci.Copy把所有服务镜像聚合成一个MediaTypeImageIndex该 index 的Subject指向 Compose 项目 manifestartifactType同样为application/vnd.docker.compose.project并带com.docker.compose.version注解由于强制 resolve digests消费者拉取 index 时拿到的镜像内容与发布时刻完全一致。这样应用 Compose 定义 全部镜像成为一个仓库内自包含的整体。端到端验证发布后如何消费e2e 测试TestPublishpkg/e2e/publish_test.go给出了完整的发布—消费闭环可以直接照搬到本地实操# 1. 起一个本地 registry:3 docker run --name reg -P -d registry:3 # 2. 发布 Compose 项目fixture 为 compose.yaml compose-override.yaml docker compose -f compose.yaml -f compose-override.yaml \ -p myapp publish --with-env --yes registry-host:port/test:test # 3. 用 oci:// URI 直接以该工件为 compose 文件查看解析结果 docker compose -f oci://registry-host:port/test:test config # 4. 甚至可以直接 up docker compose -f oci://registry-host:port/test:test up测试断言了config输出与原始 Compose 语义一致服务环境、镜像、网络并特别覆盖了一个回归场景up会二次加载远程工件来枚举待插值变量此时必须继承--insecure-registry对应 pkg/e2e/publish_test.go 中对 docker/compose#13824 的注释。发布用的 fixture 可参考 pkg/e2e/fixtures/publish/oci/compose.yaml其中extends.yaml作为 extends 父文件同目录存放。各预检路径的 e2e 断言同样可查bind mount 提示接受/拒绝pkg/e2e/publish_test.go、纯 build 项目被拒pkg/e2e/publish_test.go、本地 include 被拒pkg/e2e/publish_test.go、敏感数据全类别列出pkg/e2e/publish_test.go。使用前提与注意事项小结适用版本前提以当前仓库github.com/docker/compose/v5的源码为准--app、--with-env、digest 固定等行为均属该版本实现旧版 CLI 行为可能不同。硬性限制含本地include的项目、纯build无image的服务无法发布命令会直接报错而非进入交互。安全默认值默认不发布 env 文件内容env_file 声明、可疑键名环境字面量、字面config.content、bind mount 声明、扫出的密钥都会触发交互确认-y会跳过所有确认CI 场景下请先确认声明内容确实可公开。仓库兼容性绝大多数场景无需关心--oci-version自动1.1 优先、4xx 回退 1.0已覆盖主流仓库仅当目标仓库行为异常或需要复现工件形态时才显式指定。路径安全设计发布的工件中不含发布者本地路径——env 文件与 extends 父文件一律以路径哈希占位符引用pkg/compose/publish.go这是消费端可以安全复用该工件的前提。【免费下载链接】composeDefine and run multi-container applications with Docker项目地址: https://gitcode.com/GitHub_Trending/compose/compose创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价