禁用特定RUN命令的缓存


101

每次构建Docker映像时RUN,我都希望在Dockerfile中运行一些命令-no-cache

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

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


1
禁用单个命令的缓存后,如果结果与过去的缓存运行不匹配,则需要重新构建所有其余步骤。这是您的目标,还是希望仅重建单个层,并以某种方式将其注入到先前缓存的数据存储的位置?
BMitch

2
我希望重建特定的层,例如“ git pull”命令。现在,即使回购已更新,“ git pull”命令也将被缓存。
Vingtoft

2
通过传递未使用的参数来强制拉动是很容易的。但是,重新构建该缓存条目的结果是,随后的所有层都需要重新构建。有关示例,请参见我的回答
BMitch

如果要在git remote更改后使缓存无效,请查看:如何防止Dockerfile缓存git clone。所有对关联答案的贡献都归功于@anq
hpgmiskin

Answers:


82

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

本期评论中所建议,可以添加一个构建参数块(名称可以是任意的):

ARG CACHEBUST=1 

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

当然,这也会禁用所有后续块的缓存,因为中间映像的哈希值将有所不同,这考虑到docker当前的工作方式,从而使真正的选择性缓存禁用了一个重要的问题。


1
似乎不再工作了,只是进入了---> Using cache我的``ARG CACHEBUST = 1`行...(是的,我确实--build-arg CACHEBUST=$(date +%s)在我的
docker

也不适合我,也许是平台相关的。我会期望任何ARG更改都会使缓存无效。
奥利弗

6
您必须添加,RUN echo "$CACHEBUST"因为仅使用ARG将不会使缓存无效
Sidharth V

这个回答解决了我的问题在这里:stackoverflow.com/questions/63709147/...
夏皮罗雅各布·

28

采用

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

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

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


3
如果random.org决定更改该端点,将会发生什么?您将如何控制这种行为?
Andres Leon Rangel

@AndresLeonRangel诚然,这不是Docker功能,而是一种使用Docker语法和知名Web服务的骇客,已有20多年的历史了,但是您说的很对,他们可能会弃用该端点,实际上是现在查看他们的文档。我什至找不到“ randbyte”终结点,并且它们目前处于beta版。您可以1)继续使用此端点直到失败,2)使用其新端点(直到失败)或3)编写自己的随机端点,在这种情况下,您可以完全控制:)
史蒂夫

3
这几次失败了...当站点关闭时!!!我认为这不是完美的解决方案。添加失败:无法获取状态为503 Service Unavailable的random.org/cgi-bin/randbyte?nbytes=10&format=h:<!DOCTYPE HTML>
Kathi

1
random.org添加了DDOS保护,该保护现在打破了该解决方案
Brad Root

它不起作用,并且给定的addess返回503。如果您不想阻塞管道,请不要使用此解决方案
OlegI

9

您可以直接将Dockerfile分为几个部分,构建映像,然后在下一个Dockerfile的开头从FROMimage生成映像,并在有或没有缓存的情况下构建映像


1
这样是否可以更新基本docker映像中的提交层?
user_mda



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
# (/programming/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提供了基本原理。


-2

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

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

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


10
写入那些随机字节的结果也将被缓存,因此,如果在该命令之前没有文件更改,则不会再次运行该命令。这什么也解决不了。
冰冷的反抗
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.