Jenkins在构建时是否会缓存依赖项和Docker镜像层?

7
我正在开发一个React应用程序,将其放入Docker镜像中。我想使用Jenkins自动化构建镜像的步骤。
这是我的当前的Jenkinsfile...
pipeline {

    agent any

    stages {
        stage('Build') {
            steps {
                script {
                    def commitHash = GIT_COMMIT.take(7)
                    echo 'Building Docker image for commit hash: ' + commitHash
                    def customImage = docker.build("myImage")
                }
            }
        }
    }

}

图片本身已成功创建。我现在想知道: 1. Jenkins每次构建时是否会下载我的package.json中的所有依赖项? 2. Jenkins每次构建时是否会下载所有图层?

还是Jenkins会注意到依赖项和/或图像图层已经存在?

1个回答

13

TL;DR

取决于构建代理使用的docker守护程序,每个docker守护程序都有自己的缓存。


更详细的说明

您正在使用某个插件(docker-workflow?),该插件为您的管道提供docker.build()步骤。默认情况下,此函数尝试在代理的localhost上使用docker守护进程(通常尝试使用套接字/var/run/docker.sock)。您还可以在管道内部配置要使用的docker守护程序,方法是使用docker.withServer(){}块。

守护程序存储/缓存图层,因此只要跨构建使用相同的守护程序,它们也共享公共缓存。

如果您将构建分发到多个代理,并且每个代理都使用自己的本地主机docker守护程序,则它们不共享公共缓存。

官方文档中对此进行了更详细的解释。他们提到的另一种技术是通过共享构建代理上的本地卷与docker镜像构建来缓存容器数据(Caching data for containers部分)。例如,您可以将node deps的卷挂载到连续的docker镜像构建中。这样,即使清除了docker缓存,也不会在每个构建中重新下载所有node deps。

总之,Jenkins不能自动为您缓存。缓存是由您使用的构建工具的范围内的事情。您必须注意将其正确地纳入到CI环境的需求中。不过,当然可以实现。

小提示:在CI构建中拥有一个干净的Docker构建缓存可能是个好主意。过去我们遇到了旧的Docker构建缓存破坏我们镜像的问题。但是,如果您的构建时间很长,则清除缓存可能不是一个选项-至少不是在每次构建之后。


你所指的是哪种损坏?你的问题是来自于Docker重用先前的层,因为其层失效算法决定可以重用该层吗?还是由于Docker做错了事情而导致数据实际上被损坏了?因为层失效虽然有一些微妙和棘手之处,但绝对可以解决,如果可以进行战略性的层失效,确保正确的层(重新)使用,那么失去缓存将是一件遗憾的事情。 - ErikE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接