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

标签 gitlab gitlab-ci gitlab-ci-runner docker-build

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

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

因此构建是浪费时间,因为推送不会产生效果,因为图像已经在 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/

最佳答案

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

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

- 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 管道并为构建和推送公共(public)项以及构建子项目时创建可选阶段和触发器。

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

关于Gitlab CI : How to avoid rebuilding of images on each commit,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55258711/

相关文章:

docker - 从 DinD 内部运行的容器访问 GitLab CI 服务

raspberry-pi - 覆盆子pi上kubernetes上的gitlab-runner-找不到容器 “helper”

ruby-on-rails - 以非root用户身份在Gitlab CI中运行Elasticsearch

git - 致命的 : could not read Username for 'https://gitlab.com' : terminal prompts disabled

gitlab - 带有美元符号的 secret 变量设置不正确

GitLab:是否可以在特定的运行者上运行管道?

azure - 如何将 Azure AKS Kubernetes 集群自签名 CA 添加到 GitLab CI/CD Kubernetes 集成?

php - PHPUnit 测试期间 GitLab-CI 出现 file_get_contents 问题

java - gitlab ci : mysql build and restore db dump

docker - Gitlab CI运行docker review应用