如何实现关联Docker镜像的CI并行构建?替代INCLUDE方案
解决方案与分析
可行方案(无外部工具依赖)
1. 优化CI构建流程:本地复用base镜像,跳过中间推送拉取
当前CI流程可能存在「构建base镜像→推送到仓库→拉取远程镜像→构建devcontainer」的冗余环节,推送+拉取会消耗额外时间。可以调整步骤,直接在本地复用刚构建的base镜像:
CI执行命令:
# 启用BuildKit加速构建(支持并行阶段、更高效的缓存) export DOCKER_BUILDKIT=1 # 构建base镜像并打本地标签 docker build -t baseimage:1 ./baseimage # 直接使用本地base镜像构建devcontainer,无需拉取远程仓库镜像 docker build -t devcontainer:1 ./devcontainer # 分别推送两个镜像到仓库 docker push registry.gitlab.com/.../baseimage:1 docker push registry.gitlab.com/.../devcontainer:1额外优化:给CI Runner配置Docker层缓存(比如GitLab CI中通过
cache挂载Docker的/var/lib/docker目录,或使用BuildKit远程缓存),重复构建时可复用已有镜像层,进一步压缩耗时。
2. 合并为多阶段Dockerfile,同时输出两个镜像
将两个Dockerfile的逻辑合并到一个文件中,利用多阶段构建复用公共层,同时生成两个独立镜像:
创建根目录的Dockerfile:
# baseimage构建阶段 ARG AMAZONLINUX_VERSION="2023" FROM amazonlinux:${AMAZONLINUX_VERSION} as baseimage # ... 原baseimage/Dockerfile的所有构建步骤 ... # devcontainer构建阶段,依赖本地baseimage阶段 FROM baseimage as devcontainer # ... 原devcontainer/Dockerfile的所有构建步骤 ...
CI执行命令:
export DOCKER_BUILDKIT=1 # 构建并导出baseimage镜像 docker build --target baseimage -t baseimage:1 . # 构建并导出devcontainer镜像(复用baseimage的构建缓存) docker build --target devcontainer -t devcontainer:1 . # 推送两个镜像到仓库 docker push registry.gitlab.com/.../baseimage:1 docker push registry.gitlab.com/.../devcontainer:1
这种方式下,BuildKit会并行处理可独立的构建步骤,devcontainer直接复用本地构建的baseimage阶段,完全避免远程镜像拉取耗时。
是否应该采用这种方式?
完全应该。两种方案均基于Docker官方原生能力,未引入任何外部工具,同时精准解决核心需求:
- 消除了镜像推送、拉取的额外耗时
- 利用BuildKit的并行构建与缓存机制大幅缩短整体构建时间
- 严格保留了两个独立的镜像,满足业务要求
内容的提问来源于stack exchange,提问作者John Dibling
相关产品推荐
相关产品推荐

