我有一个Dockerfile,从安装texlive-full软件包开始,这个版本很大,需要很长时间。如果我在本地docker build
,则在安装后创建的中间图像被缓存,后续构建很快。
但是,如果我推送到我自己的GitLab安装并启动GitLab-CI构建运行器,这似乎总是从头开始,重新加载FROM
图像,并再次执行apt-get安装。这对我来说似乎是一个巨大的浪费,所以我想弄清楚如何让GitLab DinD图像在构建之间缓存中间图像,到目前为止没有运气。
我尝试使用--cache-dir
和--docker-cache-dir
作为gitlab-runner register
命令,但无济于事。
这甚至是gitlab-runner DinD图像能够做到的吗?
我的.gitlab-ci.yml
:
build_job:
script:
- docker build --tag=example/foo .
我的Dockerfile
:
FROM php:5.6-fpm
MAINTAINER Roel Harbers <roel.harbers@example.com>
RUN apt-get update && apt-get install -qq -y --fix-missing --no-install-recommends texlive-full
RUN echo Do other stuff that has to be done every build.
我使用GitLab CE 8.4.0和gitlab / gitlab-runner:latest作为跑步者,以
开头docker run -d --name gitlab-runner --restart always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/local/gitlab-ci-runner/config:/etc/gitlab-runner \
gitlab/gitlab-runner:latest \
; \
跑步者使用以下方式注册:
docker exec -it gitlab-runner gitlab-runner register \
--name foo.example.com \
--url https://gitlab.example.com/ci \
--cache-dir /cache/build/ \
--executor docker \
--docker-image gitlab/dind:latest \
--docker-privileged \
--docker-disable-cache false \
--docker-cache-dir /cache/docker/ \
; \
这会创建以下config.toml
:
concurrent = 1
[[runners]]
name = "foo.example.com"
url = "https://gitlab.example.com/ci"
token = "foobarsldkflkdsjfkldsj"
tls-ca-file = ""
executor = "docker"
cache_dir = "/cache/build/"
[runners.docker]
image = "gitlab/dind:latest"
privileged = true
disable_cache = false
volumes = ["/cache"]
cache_dir = "/cache/docker/"
(我已尝试使用cache_dir
,docker_cache_dir
和disable_cache
的不同值,但结果相同:不进行任何缓存)
答案 0 :(得分:14)
我认为你的问题没有简单的答案。在添加一些细节之前,我强烈建议您阅读最初命名为#34的DinD维护者this blog article;不要在Docker中使用Docker for CI&#34;。
您可能会尝试将/var/lib/docker
声明为GitLab跑步者的音量。但请注意,根据您的文件系统驱动程序,您可以在主机上的AUFS文件系统上的容器中使用AUFS,这很可能会导致问题。
我建议你创建一个单独的 Docker-VM,仅用于跑步者,并从VM绑定挂载docker.sock
到你的跑步者-容器。
我们正在使用GitLab的这种设置取得了巨大的成功(大约12个月内大约有27.000次构建)。
您可以查看我们的runner with docker-compose
support,它实际上是基于GitLab跑步者的shell执行者。
答案 1 :(得分:3)
目前,您无法在GitLab Docker-in-Docker中缓存中间层。 Altough有计划添加(在下面的链接中提到)。今天你可以做些什么来加速你的DinD构建是使用覆盖文件系统。为此,您需要运行liunx内核&gt; = 3.18并确保加载覆盖内核模块。然后在gitlab-ci.yml:
中设置此变量variables:
DOCKER_DRIVER: overlay
有关更多信息,请参阅此问题,特别是关于“优化Docker Builds的状态!”的评论,请参阅“使用docker executor with dind”部分。
https://gitlab.com/gitlab-org/gitlab-ce/issues/17861#note_12991518
答案 2 :(得分:0)
对于那些不会改变的构建依赖项,您可以使用gitlab图像注册表进行手动缓存。
在CI脚本中,您无需显式调用docker build
,而是将其包装在Shell脚本中
# cat build_dependencies.sh
registry=registry.example.com
project=group/project
imagebase=$registry/$project/linux
docker pull $imagebase/devbase:1.0
if [ $? -ne 0 ]; then
docker build -f devbase.dockerfile -t $imagebase/devbase:1.0 .
docker push $imagebase/devbase:1.0
fi
...
并在您的CI中调用该脚本
...
script:
- ./build_dependencies.sh
此方法的缺点是,devbase.dockerfile
更新时,CI不会注意到这一点,因此您需要强制构建和推送新映像。因此,对于动态更改图像而言,这种方法效果不佳,但是对于您的用例来说,这似乎是一种可行的方法。