具有两个类似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
或者ADD
s 指令定义工作目录。
使用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最佳实践官方指南指出,这COPY
是ADD
大多数用途中的首选指令。
一般而言,虽然ADD
并且COPY
在功能上类似,但是COPY
是优选的。那是因为它更透明ADD
。COPY
仅支持将本地文件基本复制到容器中,同时ADD
具有一些功能(如仅限本地的tar提取和远程URL支持),这些功能并不是很明显。因此,最好的用途ADD
是将本地tar文件自动提取到图像中,如- 编写Dockerfiles的最佳实践ADD rootfs.tar.xz /
其中一个ADD
附加功能是它可以从URL复制文件,但Docker建议不要将其用于此目的。
从URL复制文件的最佳实践
如果ADD
源是URL,它将下载文件并将其复制到Docker镜像中的目标位置。码头工人表明,它往往是效率不高,从使用URL复制ADD
,这是最好的做法,以使用其他策略,包括所需的远程文件。
由于图像大小很重要,ADD
因此强烈建议不要使用从远程URL获取包。你应该使用curl
或wget
代替。这样,您可以删除提取后不再需要的文件,也不必在图像中添加其他图层。
- 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 中ADD
over 的主要推荐用法COPY
。
对于不需要ADD
tar自动提取功能的其他项目(文件,目录),您应该始终使用COPY
。
了解更多
官方Dockerfile基准进入进一步的细节COPY
,ADD
以及其他Dockerfile指令。
在编写Dockerfiles时,Docker 编写Dockerfiles的最佳实践涵盖了有关如何有效地构建Dockerfiles,图像和容器的更多技巧。