问题描述
在 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 之后缓存图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!