如何在GitLab流水线的另一Job中复用Docker多阶段构建的早期文件作为制品
从GitLab流水线的Docker多阶段构建中提取文件作为跨Job制品
问题核心
你需要在amd64架构的构建Job中,从Docker多阶段构建的builder阶段提取出/app.tar,作为GitLab制品传递给后续的s390x Job复用。当前配置的问题在于:/app.tar是Docker容器内的文件,GitLab Runner无法直接访问,无法作为制品导出。
解决步骤
1. 修改amd64 Job:将容器内的文件导出到Runner工作目录
GitLab制品只能识别Runner工作目录下的文件,因此需要先把Docker容器中的/app.tar复制到工作目录,再定义制品路径。有两种常用方法:
方法一:使用docker create + docker cp(兼容旧版Docker)
修改.gitlab-ci.yml中docker-build-amd64的script部分,先构建到builder阶段,再临时创建容器复制文件:
docker-build-amd64: variables: ARCH: x86_64 DOCKER_PULL_IMAGE: library/node:16 image: ${RUNNER_IMAGE} stage: amd64 services: - ${DOCKER_REGISTRY}/docker:18.09.7-dind artifacts: paths: - app.tar # 指向Runner工作目录的文件 expire_in: 1 hour script: # 仅构建到builder阶段并打临时标签 - docker build --target builder -t temp-builder . # 创建临时容器并复制文件到工作目录 - docker create --name temp-container temp-builder - docker cp temp-container:/app.tar ./app.tar # 清理临时资源 - docker rm temp-container - docker rmi temp-builder # 执行原本的最终镜像构建命令 - docker build ...
方法二:使用docker build --output(Docker 19.03+推荐)
利用Docker的输出导出功能,直接从builder阶段将文件导出到工作目录,步骤更简洁:
docker-build-amd64: variables: ARCH: x86_64 DOCKER_PULL_IMAGE: library/node:16 image: ${RUNNER_IMAGE} stage: amd64 services: - ${DOCKER_REGISTRY}/docker:18.09.7-dind artifacts: paths: - app.tar expire_in: 1 hour script: # 从builder阶段直接导出/app.tar到当前工作目录 - docker build --target builder --output type=local,dest=. . # 继续执行原本的最终镜像构建命令 - docker build ...
2. 配置s390x Job:获取并使用制品
s390x Job会自动下载前一阶段的制品到工作目录,只需在构建时引用即可。可以显式添加dependencies字段明确依赖关系:
docker-build-s390x: variables: ARCH: s390x DOCKER_PULL_IMAGE: node:16 stage: s390x tags: - s390x - shell dependencies: - docker-build-amd64 # 明确依赖amd64 Job的制品 script: # 在podman构建时使用工作目录中的app.tar - podman build --rm --format docker ...
3. 调整Dockerfile(可选)
如果s390x的构建需要直接使用这个tar文件,可以修改Dockerfile,从构建上下文复制而不是重新生成:
ARG ARCH FROM $DOCKER_REGISTRY/nginx:alpine # 复用从amd64 Job传递来的app.tar COPY ./app.tar /app.tar RUN tar -xf /app.tar -C /app && rm /app.tar
关键说明
- GitLab制品只能识别Runner工作目录内的文件,必须将容器内文件导出到该目录才能生效
--target builder参数可以只构建到指定阶段,避免不必要的镜像构建,节省时间和资源- 显式指定
dependencies可以确保s390x Job仅下载需要的制品,避免冗余下载
内容的提问来源于stack exchange,提问作者Thomas Seeling
相关产品推荐
相关产品推荐

