具有两个类似Dockerfile指令,COPY并且ADD,这两者都用于为包括在文件中的图像。本文将解释为什么最佳实践是使用COPY而不是ADD,除非您想要将本地tar文件自动提取到图像中。

使用COPY的最佳做法

Dockerfile指令将一个或多个本地文件或文件夹复制到Docker镜像中的目标位置。

  • COPY <source>... <destination>
  • COPY ["<source>",... "<destination>"] (包含空格的路径需要此表单)

使用COPY的示例Dockerfile

这就是你COPY在Dockerfile中使用Ruby应用程序的方法。

<span style="color:rgba(0, 0, 0, 0.843137)">




</span>

它积聚在图像中的层,先从父图像ruby:2.5.1,使用所定义FROM

Docker指令WORKDIR为其后面的COPY或者ADDs 指令定义工作目录。

使用COPY它时,会将文件从本地源(在本例  .中为当前目录中的文件)复制到定义的位置WORKDIR。在上面的示例中,第二个  .引用图像中工作目录中的当前目录。

使用COPY创建图像图层的最佳做法

Docker建议使用COPY以在不同图像层中保存不同文件上下文的方式创建图像层。这意味着重建图像是有效的。最不可能更改的文件应位于较低层,而最可能更改的文件应最后添加。

如果您有多个 Dockerfile步骤使用上下文中的不同文件,则 COPY它们是单独的,而不是一次性完成。这可确保每个步骤的构建缓存仅在特定所需文件更改时失效(强制重新执行该步骤)。
 -   编写Dockerfiles的最佳实践

上面的Dockerfile示例演示了此原则。通过复制Gemfiles,然后RUN bundle install 使用已安装的Ruby Gems创建一个图像层,可以对其进行缓存。最后两条Docker指令将应用程序的文件复制到映像中,并使用默认命令设置CMD

这意味着如果您更改任何应用程序的文件,则可以使用缓存的父级和中间层重建Docker镜像。这比从头开始构建所有这些更有效。

为什么你不应该使用ADD

ADD指令具有类似的语法COPY。除了将本地文件和目录复制到Docker镜像中的目标之外,它还具有一些其他功能

  • ADD <source>... <destination>
  • ADD ["<source>",... "<destination>"] (包含空格的路径需要此表单)

但是,Docker的Dockerfile最佳实践官方指南指出,这COPYADD大多数用途中的首选指令。

一般而言,虽然 ADD并且 COPY在功能上类似,但是 COPY是优选的。那是因为它更透明 ADDCOPY仅支持将本地文件基本复制到容器中,同时 ADD具有一些功能(如仅限本地的tar提取和远程URL支持),这些功能并不是很明显。因此,最好的用途 ADD是将本地tar文件自动提取到图像中,如-  编写Dockerfiles的最佳实践 ADD rootfs.tar.xz /

其中一个ADD附加功能是它可以从URL复制文件,但Docker建议不要将其用于此目的。

从URL复制文件的最佳实践

如果ADD源是URL,它将下载文件并将其复制到Docker镜像中的目标位置。码头工人表明,它往往是效率不高,从使用URL复制ADD,这是最好的做法,以使用其他策略,包括所需的远程文件。

由于图像大小很重要, ADD因此强烈建议不要使用从远程URL获取包。你应该使用 curlwget代替。这样,您可以删除提取后不再需要的文件,也不必在图像中添加其他图层。 
 -   Dockerfile最佳实践

例如,你应该避免做以下事情:

<span style="color:rgba(0, 0, 0, 0.843137)">

</span>

而是做一些像:

<span style="color:rgba(0, 0, 0, 0.843137)">


</span>

什么时候可以使用ADD

如果<source>是具有可识别压缩格式的本地 tar存档,则会将其作为目录自动解压缩到Docker镜像中。例如:ADD rootfs.tar.xz /。这是Dockerfiles 中ADDover 的主要推荐用法COPY

对于不需要ADDtar自动提取功能的其他项目(文件,目录),您应该始终使用COPY

了解更多

官方Dockerfile基准进入进一步的细节COPYADD以及其他Dockerfile指令。

在编写Dockerfiles时,Docker 编写Dockerfiles最佳实践涵盖了有关如何有效地构建Dockerfiles,图像和容器的更多技巧。