当 Dockerfile 命令被缓存时

Fra*_*eli 6 caching docker

我试图了解 docker 缓存对于哪些类型的命令是危险的。

这里有一些例子以及我相信会发生的事情。

在我看来,这将始终使用缓存。我关心的?
并不是真的,因为如果以前缓存安装的curl版本使我的图像正常工作,它应该仍然可以工作:

RUN apt-get update && apt-get install --no-install-recommends -yy curl
Run Code Online (Sandbox Code Playgroud)

仅当requirements.txt 与之前相同时,此 COPY 命令才会使用缓存:

COPY ./requirements.txt /opt/client_web/requirements.txt
Run Code Online (Sandbox Code Playgroud)

仅当 /opt/client_web/requirements.txt 的内容与之前完全相同时,此 RUN 命令才会缓存,否则将不会使用缓存:

RUN python3 -m pip install --default-timeout=100 -r /opt/client_web/requirements.txt
Run Code Online (Sandbox Code Playgroud)

这个 RUN 命令可能会一直缓存,这是可以的。当然,如果更新版本的 pip 发布,我不会得到它:

RUN curl https://bootstrap.pypa.io/get-pip.py > get-pip.py && python3 get-pip.py
Run Code Online (Sandbox Code Playgroud)

上述说法正确吗?

如果是的话,我们是否可以说只有当命令不涉及文件更改时才使用docker缓存?

Pie*_* B. 5

RUN apt-get update && apt-get install --no-install-recommends -yy curl
Run Code Online (Sandbox Code Playgroud)

除非前面的命令已经使缓存失效,否则该命令确实应该重新使用缓存。

仅当requirements.txt与之前相同时,第一个COPY命令才会使用缓存

COPY ./requirements.txt /opt/client_web/requirements.txt
Run Code Online (Sandbox Code Playgroud)

是的。Docker 将使用该文件的校验和来确保这一点。

仅当 /opt/client_web/requirements.txt 的内容与之前完全相同时,此行才会缓存,否则不会使用缓存。

RUN python3 -m pip install --default-timeout=100 -r /opt/client_web/requirements.txt
Run Code Online (Sandbox Code Playgroud)

不完全是,如果命令行更改,缓存将不会被重新使用。仅在以下情况下才会使用缓存:

  • 命令字符串与之前完全相同
  • 缓存未被先前的命令(例如COPY使用不同的文件)失效 - 在您的具体情况下,更改为requirements.txt

COPY仅当 this和之间没有指令时,您的陈述才是正确的RUN。放置在这两者之间的另一条指令可能会使高速缓存无效。

此外,Docker 无法知道您的命令行实际上使用了该requirements.txt文件,只有命令字符串的更改可能会告诉 Docker 在此特定步骤上使缓存无效。

这可能会一直缓存,没关系,我不介意。当然,如果更新版本的 pip 发布,我不会得到它:

RUN curl https://bootstrap.pypa.io/get-pip.py > get-pip.py && python3 get-pip.py
Run Code Online (Sandbox Code Playgroud)

是的,除非缓存因先前的指令或命令字符串更改而失效。

如果是,我们可以说仅当命令涉及更改的文件时才使用缓存。

COPY,这ADD只是 Docker 可能使缓存失效的方式之一。RUN也可能使缓存无效,不是因为涉及文件,而是因为 shell 命令的字符串发生了更改。此外,任何 Dockerfile 指令更改都可能使缓存无效,即使不涉及文件。请参阅利用构建缓存文档