禁用特定RUN命令的缓存

时间:2016-02-01 15:53:17

标签: docker

我的Dockerfile中有一些RUN命令,每次构建Docker镜像时我都想用-no-cache运行。

我理解docker build --no-cache将禁用整个Dockerfile的缓存。

是否可以为特定的RUN命令禁用缓存?

8 个答案:

答案 0 :(得分:30)

总有一个选项可以在要禁用缓存的区域之前插入一些无意义且便宜的运行命令。

正如this问题评论中提出的,可以添加构建参数块(名称可以是任意的):

ARG CACHEBUST=1 

在此类区域之前,并通过将--build-arg CACHEBUST=$(date +%s)添加为docker build参数来修改其每次运行的值(值也可以是任意的,这里是当前日期时间,以确保它在运行中的唯一性)。

当然,这也将禁用所有后续块的缓存,因为中间图像的哈希值将不同,这使得真正选择性缓存禁用了一个非平凡的问题,同时考虑了docker当前的工作原理。

答案 1 :(得分:6)

不是直接但您可以将Dockerfile分成几个部分,构建一个图像,然后在下一个Dockerfile的开头使用FROM thismage,并使用或不使用缓存构建图像

答案 2 :(得分:4)

截至2016年2月,这是不可能的。

已在GitHub

请求该功能

答案 3 :(得分:4)

另一个快速的技巧是在命令前写入一些随机字节

RUN head -c 5 /dev/random > random_bytes && <run your command>

写出5个随机字节,这将导致高速缓存未命中

答案 4 :(得分:3)

如果您的目标是包含来自 Github(或类似代码)的最新代码,则可以使用 Github API(或等效代码)通过 ADD 命令获取有关最新提交的信息。
docker build 将始终从 ADD 命令获取 URL,如果响应与上次 docker build 运行时收到的响应不同,它将不会使用后续缓存层。

例如

ADD "https://api.github.com/repos/username/repo_name/commits?per_page=1" latest_commit
RUN curl -sLO "https://github.com/username/repo_name/archive/main.zip" && unzip main.zip

答案 5 :(得分:1)

该功能是一周前添加的。

ARG FOO=bar

FROM something
RUN echo "this won't be affected if the value of FOO changes"
ARG FOO
RUN echo "this step will be executed again if the value of FOO changes"

FROM something-else
RUN echo "this won't be affected because this stage doesn't use the FOO build-arg"

https://github.com/moby/moby/issues/1996#issuecomment-550020843

答案 6 :(得分:1)

使用

ADD "https://www.random.org/cgi-bin/randbyte?nbytes=10&format=h" skipcache

要一直运行的RUN行之前。之所以可行,是因为ADD将始终获取文件/ URL,并且上述URL会在每个请求上生成随机数据,然后Docker比较结果以查看其是否可以使用缓存。

我也对此进行了测试,并且效果很好,因为它不需要任何其他Docker命令行参数,并且还可以从Docker-compose.yaml文件:)

答案 7 :(得分:0)

我相信,这与@steve的回答相比略有改善:

RUN git clone https://sdk.ghwl;erjnv;wekrv;qlk@gitlab.com/your_name/your_repository.git

WORKDIR your_repository

# Calls for a random number to break the cahing of the git clone
# (https://stackoverflow.com/questions/35134713/disable-cache-for-specific-run-commands/58801213#58801213)
ADD "https://www.random.org/cgi-bin/randbyte?nbytes=10&format=h" skipcache
RUN git pull

这使用git克隆的Docker缓存,但随后运行存储库的未缓存更新。

它似乎可以正常工作,并且运行更快,但是要感谢@steve提供了基本原理。