在 Dockerfile 中使用 ADD <url> 与 RUN wget/curl <url> 相比是否有缓存优势

Jon*_*ski 5 docker dockerfile

ADD使用而不是分层缓存失效有什么好处吗RUN

\n

背景

\n

我经常看到 Dockerfiles 安装 wget 或 curl 只是为了RUN wget \xe2\x80\xa6安装RUN curl \xe2\x80\xa6一些在包管理中找不到的依赖项。

\n

我怀疑这些可以转换为简单的ADD <url> <dest>线条,这至少可以消除向图像添加curl或wget的需要。

\n

此外,docker 守护进程似乎可以依赖 HTTP 缓存失效来通知其自己的层缓存失效。至少(例如,在没有 HTTP 缓存标头的情况下),它可以对GET资源进行哈希处理,并以与本地文件相同的方式计算失效。

\n

注意:我熟悉vs的用法,但我正在寻找选择其中一个的强有力的理由。特别是,我想知道在层缓存失效方面是否可以表现得更智能。AddRUN \xe2\x80\xa6ADD <url>

\n

eri*_*sas 7

当然。

RUN指令不会使缓存无效,除非其文本发生更改。因此,如果远程文件已更新,您将无法获取它。Docker 将使用缓存层。

ADD指令将始终下载文件,如果文件的校验和不再匹配,则缓存将失效。

我建议使用ADD代替RUN wget ...or RUN curl ...。我想人们会使用后者,因为它更熟悉,但ADD指令非常强大。它可以解压文件并设置所有权。避免下载进程运行不需要的任何包也被认为是最佳实践(尽管有多种方法可以实现此目的,例如使用多阶段构建)。

关于缓存失效的文档:

https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#leverage-build-cache


Ser*_*gey 5

最好使用RUN wget \xe2\x80\xa6RUN curl \xe2\x80\xa6下载存档而不是ADD. 这允许您在同一命令中提取存档文件并删除下载的文件RUN。这可以防止下载的文件存储在图像中。

\n

正如 Docker 文档所述:“强烈建议不要使用 ADD 从远程 URL 获取包

\n

避免使用ADD下载存档,然后在单独的RUN命令中提取它,因为这将创建一个将存储在映像中的中间文件。由于 Docker 的工作原理,后续的\nRUN命令只能将文件标记为已删除,但并不能真正删除它。例如,以下 Dockerfile 将创建一个big.tar.xz在映像中调用的中间文件:

\n
ADD https://example.com/big.tar.xz /usr/src/things/\nRUN tar -xJf /usr/src/things/big.tar.xz -C /usr/src/things\nRUN make -C /usr/src/things all\n
Run Code Online (Sandbox Code Playgroud)\n

相反,您可以使用单个RUN命令来下载存档、解压并运行 make 命令,如以下 Dockerfile 所示:

\n
RUN mkdir -p /usr/src/things \\\n    && curl -SL https://example.com/big.tar.xz \\\n    | tar -xJC /usr/src/things \\\n    && make -C /usr/src/things all\n
Run Code Online (Sandbox Code Playgroud)\n

这个Dockerfile不会创建任何中间文件,下载的文件也不会存储在镜像中。

\n