首页 > 解决方案 > Gitlab CI:如何避免在每次提交时重建图像

问题描述

我正在使用 Gitlab CI 来存储和部署 docker 图像,但我遇到了一个大问题。Gitlab CI 在每次提交时重建所有图像。

第一步是构建我的通用图像,大约需要 8 分钟。目前我只修改子图像,但公共图像仍然在每次提交时重建。

因此构建是浪费时间,因为推送不会产生影响,因为图像已经在 Gitlab 存储库中。

当图像已经在您的 Gitlab 存储库中时,如何避免重建图像?

下面 gitlab-ci.yml

build:
   tags:
       - docker_ci_build
   services:
       - docker:dind
   script:
       - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
       - >
           docker build 
           -t $CI_PROJECT/common:6.0.1 common

在 dockerfile 下面:

FROM ubuntu:bionic
RUN apt-get update && \
     DEBIAN_FRONTEND=noninteractive \
     apt-get install -y packages && \
     apt-get clean && \
     rm -rf /var/lib/apt/lists/*
COPY file.conf /etc/common/

标签: gitlabgitlab-cigitlab-ci-runnerdocker-build

解决方案


缓存似乎比我最初想象的要复杂,并且各种拉取选项的 docker 文档没有提到任何细微差别。

如果 docker 镜像可能存在也可能不存在,您实际上可以调整 docker pull 命令以通过您的构建,即使拉取失败:

- docker image pull $LATEST || true

这将提取图像 $LATEST 如果它存在,否则将继续您的构建。下一步是确保您的构建实际上可以使用它。

docker build的--pull选项看起来就像你想要的,docker 的文档说

--pull 总是尝试拉取更新版本的镜像

但似乎它实际上并没有为您正在构建的实际图像做任何事情。更有希望的是--cache-from,它可以让您命名 docker 可以从中缓存的图像。然而,在我的简单测试中,我没有看到 docker 实际使用我的缓存,可能是因为它在 docker 映像中没有足够的层来利用缓存。

- docker image pull $LATEST_IMAGE || true
- docker build --pull -t $TAGGED_IMAGE --cache-from $LATEST_IMAGE .
- docker tag $TAGGED_IMAGE $LATEST_IMAGE
- docker push $LATEST_IMAGE
- docker push $TAGGED_IMAGE

如果您的构建映像是多阶段构建,这可能会更有用,并且实际上可以利用缓存。或者,如果图像存在,您可以调整 gitlab-ci 脚本以避免构建。

或者,您可能希望查看 gitlab-ci 管道并为构建和推送通用以及构建子项目时创建可选阶段和触发器。

variables在文件开头的一个部分中定义了变量Latest 是用标记定义的,该:latest标记基本上是该项目的任何CI 分支的最新构建。$TAGGED_IMAGE使用 git SHA定义:$CI_COMMIT_SHORT_SHAdocker 镜像的哪些标签,这使得 kubernetes 部署到开发环境更容易跟踪。


推荐阅读