Gitlab docker executor - 在before_script之后缓存图像

时间:2016-01-15 22:12:16

标签: docker gitlab gitlab-ci gitlab-ci-runner

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,我认为该命令可以缓存所有不是我项目副产品的内容,但它没有似乎没有任何效果。

有没有办法得到我想要的行为?

2 个答案:

答案 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个跑步者和只保留一个图像,这种维护可以在您自己的工作站或任何机器上完成。

我个人认为这比尝试在跑步者的图像中缓存任何内容要好得多。当您创建新分支以在较新版本的依赖项上测试代码时尤其如此。如果您有缓存,那么您的稳定和开发分支将面临具有不同测试环境的问题。在我看来,测试应该在尽可能干净的环境中运行,这种设置可以实现这一点。