在gitlab-ci
中,.gitlab-ci.yml
文件中有一个选项可以在任何实际脚本运行之前执行命令,称为before_script
。 .gitlab-ci.yml
示例说明了在此处安装辅助程序。但是,我注意到的是,使用docker执行程序时,Docker中没有缓存这些更改。我天真地假设在运行这些命令后,docker会缓存图像,因此对于下一次运行或测试,docker只会加载before_script
之后生成的缓存图像。这将大大加快构建速度。
举个例子,我的.gitlab-ci.yml
看起来有点像:
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处理适当的缓存,那就更好了。
cache
中还有一个.gitlab-ci.yml
命令,我尝试将其设置为untracked: true
,我认为该命令可以缓存所有不是我项目副产品的内容,但它没有似乎没有任何效果。
有没有办法得到我想要的行为?
答案 0 :(得分:8)
您可以添加一个舞台来首先构建图像。如果图像没有任何变化,则舞台将非常短,不到1秒。
您可以在以下阶段使用该图像,从而加快整个过程。
这是.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镜像。所以,跑步者居住的主机应该安装了Docker Engine。我发现这个解决方案比docker和another solutions中的docker更适合我的需求。
此外,我正在使用私有注册表,这就是我使用$CI_REGISTRY*
变量的原因,但您可以使用DockerHub而无需指定注册表。但问题是在DockerHub上进行身份验证。
答案 1 :(得分:2)
我处理这个的方式是我在Docker Hub上为每个项目都有自定义图像,并从.gitlab-ci.yml
引用它们。如果我需要一个新的依赖项,我编辑用于创建初始映像的Dockerfile,重新构建映像,并使用特定标记对其进行标记并推送到Docker Hub。
cat "RUN apt-get install gcc" >> Dockerfile
ID=$(docker build)
docker tag $ID ACCOUNT/gitlab_ci_image:gcc
docker push ACCOUNT/gitlab_ci_image
然后我更新.gitlab-ci.yml
文件以指向该特定版本的图像。
image: ACCOUNT/gitlab_ci_image:gcc
build:
script:
- cd project && make
这允许我根据我尝试测试的提交而具有不同的依赖关系(因为该提交中的gitlab-ci.yml
文件告诉运行器使用哪个)。它还可以防止每次在特定跑步者上运行测试时都需要安装依赖项,因为跑步者只要不改变就会重复使用相同的图像。
另一个好处是,对于Docker Hub上托管的图像,如果跑步者需要一个它本地没有的特定标签,它将自动抓取正确的标签,这样你就可以拥有10个跑步者和只保留一个图像,这种维护可以在您自己的工作站或任何机器上完成。
我个人认为这比尝试在跑步者的图像中缓存任何内容要好得多。当您创建新分支以在较新版本的依赖项上测试代码时尤其如此。如果您有缓存,那么您的稳定和开发分支将面临具有不同测试环境的问题。在我看来,测试应该在尽可能干净的环境中运行,这种设置可以实现这一点。