在不提供外部构建参数的情况下,Dockerfile 中的 Bust 缓存 bust

Cli*_*ick 6 docker dockerfile

我们有一个 Dockerfile,在某个时候不希望缓存发生。

目前我们正在使用

ENV CACHE_BUST=$($RANDOM)

经过进一步检查,有趣的是,它被缓存了:

Step 1/1 : ENV CACHE_BUST=$($RANDOM) ---> Using cache

有没有办法从 Dockerfile 内部破坏缓存,而无需build-argdocker build . --build-arg CACHE_BUST=$(date +%s)在构建步骤中传入唯一的(Like )?

BMi*_*tch 13

更新:回顾这一点,看起来您以两种方式错误地注入了缓存清除选项:

  1. ENV不是一个ARG
  2. $(x)语法不是变量扩展,您需要大括号 ( ${}),而不是圆括号 ( $())。

要在下一个运行行中断缓存,语法为:

ARG CACHE_BUST
RUN echo "command with external dependencies"
Run Code Online (Sandbox Code Playgroud)

然后构建:

docker build --build-arg CACHE_BUST=$(date +%s) .
Run Code Online (Sandbox Code Playgroud)

为什么这样有效?因为在构建过程中, 的值会作为环境变量ARG注入到RUN命令中。更改环境变量会导致新版本的缓存未命中。


要破坏缓存,需要更改输入之一。如果正在运行的命令相同,即使该命令具有已更改的外部依赖项,缓存也将被重用,因为 docker 无法看到这些外部依赖项。

解决此问题的选项包括:

  1. 传递更改的构建参数(例如将其设置为日期戳)。
  2. 使用 COPY 或 ADD 更改包含在映像中的文件。
  3. 使用该--no-cache选项运行您的构建。

由于您不想执行选项 1,因此有一种方法可以在特定行上执行选项 3,但前提是您可以将 Dockerfile 分成两部分。第一个 Dockerfile 包含您今天所拥有的所有行,直到您想要破坏缓存为止。然后第二个 Dockerfile 有一个 FROM 行依赖于第一个 Dockerfile,您可以使用该--no-cache选项构建它。例如

Dockerfile1:

FROM base
RUN normal steps
Run Code Online (Sandbox Code Playgroud)

Dockerfile2

FROM intermediate
RUN curl external.jar>file.jar
RUN other lines that cannot be cached
CMD your cmd
Run Code Online (Sandbox Code Playgroud)

然后构建:

docker build -f Dockerfile1 -t intermediate .
docker build -f Dockerfile2 -t final --no-cache .
Run Code Online (Sandbox Code Playgroud)

我能想到的唯一其他选择是使用BuildKit制作一个新的前端,它允许您注入显式缓存中断或导致缓存中断的唯一变量。


Nic*_*lay 7

您可以ADD通过从稳定源下载一些动态页面来添加图层Dockerfile。图像将始终在不使用缓存的情况下重新构建。

只是一个例子Dockerfile

FROM alpine:3.9
ADD https://google.com cache_bust
RUN apk add --no-cache wget
Run Code Online (Sandbox Code Playgroud)

ps我相信你知道这个docker build --no-cache选项。