如何防止 Dockerfile 指令被缓存?
How can I prevent a Dockerfile instruction from being cached?
在我的 Dockerfile
中,我使用 curl
或 ADD
下载最新版本的存档,例如:
FROM debian:jessie
...
RUN apt-get install -y curl
...
RUN curl -sL http://example.com/latest/archive.tar.gz --output archive.tar.gz
...
ADD http://example.com/latest/archive2.tar.gz
...
使用curl
或ADD
的RUN
语句创建自己的图像层。这将用作将来执行 docker build
.
的缓存
问题:如何禁用该指令的缓存?
如果能有像缓存失效这样的东西在那里工作会很棒。例如。通过使用 HTTP ETags 或查询 last modified header 字段。这样就可以根据 HTTP headers 进行快速检查,以确定是否可以使用缓存层。
我知道一些卑鄙的把戏可能会有所帮助,例如改为在 RUN
语句中执行下载 shell 脚本。它的文件名将在我们的构建系统触发 docker build
之前更改。我可以在该脚本中进行 HTTP 检查。但是我需要将最后使用的 ETag 或 last modified 存储到某个文件中。我想知道是否有一些我可以在这里使用的更干净和 native Docker 功能。
docker build --no-cache 会使所有 命令的缓存无效。
Dockerfile ADD command used to have the cache invalidated. Although it has been improved 最近 docker 版本:
Docker is supposed to checksum any file added through ADDand then decide if it should use the cache or not.
所以如果添加的文件发生变化,缓存应该为ADD
命令失效。
Issue 1326提到其他技巧:
This worked.
RUN yum -y install firefox #redo
So it looks like Docker will re-run the step (and all the steps below it) if the string I am passing to RUN
command changes in anyway - even it's just a comment.
The docker cache is used only, and only if none of his ancestor has changed (this behavior makes sense, as the next command will add change to the previous layer).
The cache is used if there isn't any character which has changed (so even a space is enough to invalidate a cache).
在命令后添加 && exit 0
将使缓存从那里失效。
示例:
RUN apt-get install -y unzip && exit 0
可以指定构建时参数以从该步骤开始强制中断缓存。例如,在您的 Dockerfile 中,放入
ARG CACHE_DATE=not_a_date
然后在每个新版本中为该参数赋予一个新值。最好的当然是时间戳。
docker build --build-arg CACHE_DATE=$(date +%Y-%m-%d:%H:%M:%S) ...
确保该值为不带空格的字符串,否则docker客户端会误认为是多个参数。
请参阅 Issue 22832 上的详细讨论。
在我的 Dockerfile
中,我使用 curl
或 ADD
下载最新版本的存档,例如:
FROM debian:jessie
...
RUN apt-get install -y curl
...
RUN curl -sL http://example.com/latest/archive.tar.gz --output archive.tar.gz
...
ADD http://example.com/latest/archive2.tar.gz
...
使用curl
或ADD
的RUN
语句创建自己的图像层。这将用作将来执行 docker build
.
问题:如何禁用该指令的缓存?
如果能有像缓存失效这样的东西在那里工作会很棒。例如。通过使用 HTTP ETags 或查询 last modified header 字段。这样就可以根据 HTTP headers 进行快速检查,以确定是否可以使用缓存层。
我知道一些卑鄙的把戏可能会有所帮助,例如改为在 RUN
语句中执行下载 shell 脚本。它的文件名将在我们的构建系统触发 docker build
之前更改。我可以在该脚本中进行 HTTP 检查。但是我需要将最后使用的 ETag 或 last modified 存储到某个文件中。我想知道是否有一些我可以在这里使用的更干净和 native Docker 功能。
docker build --no-cache 会使所有 命令的缓存无效。
Dockerfile ADD command used to have the cache invalidated. Although it has been improved 最近 docker 版本:
Docker is supposed to checksum any file added through ADDand then decide if it should use the cache or not.
所以如果添加的文件发生变化,缓存应该为ADD
命令失效。
Issue 1326提到其他技巧:
This worked.
RUN yum -y install firefox #redo
So it looks like Docker will re-run the step (and all the steps below it) if the string I am passing to
RUN
command changes in anyway - even it's just a comment.The docker cache is used only, and only if none of his ancestor has changed (this behavior makes sense, as the next command will add change to the previous layer).
The cache is used if there isn't any character which has changed (so even a space is enough to invalidate a cache).
在命令后添加 && exit 0
将使缓存从那里失效。
示例:
RUN apt-get install -y unzip && exit 0
可以指定构建时参数以从该步骤开始强制中断缓存。例如,在您的 Dockerfile 中,放入
ARG CACHE_DATE=not_a_date
然后在每个新版本中为该参数赋予一个新值。最好的当然是时间戳。
docker build --build-arg CACHE_DATE=$(date +%Y-%m-%d:%H:%M:%S) ...
确保该值为不带空格的字符串,否则docker客户端会误认为是多个参数。
请参阅 Issue 22832 上的详细讨论。