Gitlab CI:如何避免在每次提交时重建图像

Gitlab CI: How to avoid rebuilding of images on each commit

我正在使用 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

在 docker 文件下方:

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/

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

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

- docker image pull $LATEST || true

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

docker 构建的 --pull 选项似乎是您想要的,docker 的文档说

--pull Always attempt to pull a newer version of the image

但看起来它实际上对您正在构建的实际图像没有任何作用。更有前途的是 --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

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

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

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