本文介绍了Gitlab docker executor - 在 before_script 之后缓存图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

gitlab-ci 中有一个选项在 .gitlab-ci.yml 文件在任何实际脚本运行之前执行命令,称为 before_script..gitlab-ci.yml 示例说明了在此处安装辅助程序.但是,我注意到的是,当使用 docker 执行器时,这些更改不会缓存在 Docker 中.我天真地假设在运行这些命令之后,docker 会缓存图像,因此在下一次运行或测试时,docker 只会加载 before_script 之后生成的缓存图像.这将大大加快构建速度.

In gitlab-ci there's an option in the .gitlab-ci.yml file to execute commands before any of the actual script runs, called before_script. .gitlab-ci.yml examples illustrate installing ancillary programs here. However, what I've noticed is that these changes are not cached in Docker when using a docker executor. I had naively assumed that after running these commands, docker would cache the image, so for the next run or test, docker would just load the cached image produced after before_script. This would drastically speed up builds.

举个例子,我的 .gitlab-ci.yml 有点像:

As an example, my .gitlab-ci.yml looks a little like:

image: ubuntu

before_script:
    - apt-get update -qq && apt-get install -yqq make ...

build:
    script:
        - cd project && make

一种可能的解决方案是转到运行器机器并创建一个 docker 映像,该映像可以构建我的软件而无需任何其他安装,然后在 yaml 文件的 image 部分中引用它.这样做的缺点是,每当我想添加依赖项时,我都需要登录到运行器机器并在构建成功之前更新映像.如果我只需将依赖项添加到 apt-get install 的末尾并让 docker/gitlab-ci 处理适当的缓存,那就更好了.

A possible solution is to go to the runner machine and create a docker image that can build my software without any other installation and then reference it in the image section of the yaml file. The downside of this is that whenever I want to add a dependency, I need to log in to the runner machine and update the image before builds will succeed. It would be much nicer if I just had to add the dependency to to the end of apt-get install and have docker / gitlab-ci handle the appropriate caching.

.gitlab-ci.yml中还有一个cache命令,我试过设置成untracked: true,我以为会缓存所有不是我项目副产品的东西,但它似乎没有任何效果.

There is also a cache command in .gitlab-ci.yml, which I tried setting to untracked: true, which I thought would cache everything that wasn't a byproduct of my project, but it didn't seem to have any effect.

有什么方法可以得到我想要的行为吗?

Is there any way to get the behavior I desire?

推荐答案

您可以添加一个阶段来首先构建图像.如果图像没有任何变化,这个阶段会很短,不到 1 秒.

You can add a stage to build the image in first place. If the image doesn't have any change, the stage will be very short, under 1 second.

您可以在以下阶段使用该图像,加快整个过程.

You can use that image on the following stages, speeding up the whole process.

这是一个.gitlab-ci.yml的例子:

stages:
  - build_test_image
  - test

build_test:
  stage: build_test_image
  script:
    - docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN $CI_REGISTRY
    - docker build -t $CI_REGISTRY_IMAGE:test -f dockerfiles/test/Dockerfile .
    - docker push $CI_REGISTRY_IMAGE:test
  tags:
    - docker_build

test_syntax:
  image: $CI_REGISTRY_IMAGE:test
  stage: test
  script:
    - pip install flake8
    - flake8 --ignore=E501,E265 app/

查看标签 docker_build.该标签用于强制在具有该标签的运行器上执行阶段.该运行器的执行器是 shell,它仅用于构建 Docker 映像.所以,runner 所在的主机应该已经安装了 Docker Engine.我发现这个解决方案比 docker in docker 和 另一种解决方案.

Look at the tag docker_build. That tag is used to force the execution of the stage on the runner which has that tag. The executor for that runner is shell, and it's used only to build Docker images. So, the host where the runner lives should have installed Docker Engine. I found this solution suits better my needs than docker in docker and another solutions.

另外,我使用的是私有注册表,这就是我使用 $CI_REGISTRY* 变量的原因,但您可以使用 DockerHub 而无需指定注册表.不过,问题在于在 DockerHub 上进行身份验证.

Also, I'm using a private registry, that's why I'm using $CI_REGISTRY* variables, but you can use DockerHub without need to specify the registry. The problem would be to authenticate on DockerHub, though.

这篇关于Gitlab docker executor - 在 before_script 之后缓存图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-30 19:23