【问题标题】:docker build cache busting with apt-getdocker 使用 apt-get 构建缓存破坏
【发布时间】:2022-02-02 04:43:35
【问题描述】:

我的理解是,如果RUN命令“string”本身没有改变(即要安装的包列表没有改变),docker引擎使用缓存中的图像进行相同的操作。这也是我的经验:

...
Step 2/6 : RUN apt update &&      DEBIAN_FRONTEND=noninteractive     apt install -y     curl               git-all            locales            locales-all        python3            python3-pip        python3-venv       libusb-1.0-0       gosu        &&     rm -rf /var/lib/apt/lists/*
 ---> Using cache
 ---> 518e8ff74d4c
...

不过,Dockerfile best practices document 官方是这么说 apt-get 的:

使用RUN apt-get update && apt-get install -y 可确保您的 Dockerfile 安装最新的软件包版本,无需进一步编码或手动干预。这种技术被称为“缓存破坏”。

如果我将新包添加到列表中,这是正确的,但如果我不修改列表,则不是。

我的理解是否正确,或者我在这里遗漏了什么?

如果是,我是否可以假设,如果 Ubuntu 基础映像也已更新(这会使整个缓存失效),我只会在 apt-get install 中获得更新的软件包?

【问题讨论】:

    标签: docker ubuntu apt-get


    【解决方案1】:

    你切断了中间的报价。报价的其余部分包括一个非常重要的条件:

    您还可以通过指定包版本来实现缓存清除。这称为版本固定,例如:

    RUN apt-get update && apt-get install -y \
        package-bar \
        package-baz \
        package-foo=1.3.*
    

    因此,您在该示例中运行的命令每次都会通过更改列表中包的固定版本来更改。请注意,除了更改命令运行之外,您还可以更改环境,效果相同,使用build arg as described in this answer

    【讨论】:

    • 谢谢,@BMitch。我故意切断了这句话,因为它说“你可以实现...”,所以我的理解是使用固定版本是一个附加选项,但它应该可以工作也没有它。但是,假设版本是固定的:docker 怎么知道这不是已经有缓存的命令?它会分析命令吗?
    • @TiborTakács 它正在查看正在执行的字符串以及任何输入(环境变量和之前的阶段)。如果字符串发生变化(或输入与之前不匹配),则为缓存未命中,它会创建一个新层而不是重用旧层。
    • 这符合我的理解,谢谢你的精彩总结。这意味着尽管不修改命令本身,docker build 将获取缓存的图像(如果存在)。因此,如果 package-foo 安装了版本 1.3.**0**,则下一个 docker build 将不会选择 1.3.**1**,因为 RUN 命令没有更改。这是正确的吗?
    • @TiborTakács 只要缓存存在,就是正确的。如果您在没有缓存的情况下构建(通过标志或在不存在缓存的机器上),那么您的构建将产生不同的图像。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-06
    • 2012-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-27
    • 1970-01-01
    相关资源
    最近更新 更多