docker - 在不提供外部构建参数的情况下,在 Dockerfile 中破坏缓存

标签 docker dockerfile

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

目前我们正在使用

ENV CACHE_BUST=$($RANDOM)

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

步骤 1/1:ENV CACHE_BUST=$($RANDOM) ---> 使用缓存

有没有办法从 Dockerfile 内部破坏缓存而不传递唯一的 build-arg (例如 docker build . --build-arg CACHE_BUST=$(date +%s)) 在构建步骤中?

最佳答案

更新:回顾这一点,您似乎以两种方式错误地注入(inject)了缓存清除选项:

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

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

ARG CACHE_BUST
RUN echo "command with external dependencies"

然后构建:

docker build --build-arg CACHE_BUST=$(date +%s) .

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

<小时/>

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

解决此问题的选项包括:

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

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

Dockerfile1:

FROM base
RUN normal steps

Dockerfile2

FROM intermediate
RUN curl external.jar>file.jar
RUN other lines that cannot be cached
CMD your cmd

然后构建:

docker build -f Dockerfile1 -t intermediate .
docker build -f Dockerfile2 -t final --no-cache .

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

关于docker - 在不提供外部构建参数的情况下,在 Dockerfile 中破坏缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55619593/

相关文章:

linux - Docker COPY 命令授予 777 对复制文件的访问权限

docker - 如何链接前端和后端Docker容器

bash - Docker:如何将 bash 与基于 Alpine 的 docker 镜像一起使用?

windows - 构建docker镜像时无法npm安装依赖项

docker - 从 Alpine 图像中捕获 SIGTERM

elasticsearch - Docker-compose '' NoneType'不可迭代'

amazon-ec2 - Docker隐藏调用容器的IP

python - Pip3 无法在 docker build 期间安装 requirements.txt

linux - 如何在 Dockerfile 中使用here-strings?

docker - Docker撰写构建副本失败