Dockerfile中的COPY和ADD命令有什么区别?我什么时候可以使用其中一个命令而不是另一个命令?

COPY <src> <dest>

COPY指令将从<src>复制新文件,并将它们添加到路径<dest>的容器文件系统中

ADD <src> <dest>

ADD指令将从<src>复制新文件,并将它们添加到路径<dest>的容器文件系统中。


当前回答

COPY将文件/目录从主机复制到图像。

ADD将文件/目录从主机复制到映像,但也可以获取远程URL、提取TAR文件等。。。

使用COPY将文件和/或目录复制到构建上下文中。

使用ADD下载远程资源、提取TAR文件等。。

其他回答

COPY不支持URL方案的<src>。COPY不会解压缩压缩文件。对于指令<src><dest>,如果<src>是tar压缩文件,且<dest>不以斜杠结尾:ADD将<dest>视为一个目录,并将<src>解压缩到该目录。COPY将<dest>视为一个文件,并将<src>写入其中。COPY支持通过--from arg覆盖生成上下文。

从Docker文档:

添加或复制虽然ADD和COPY功能相似,但一般来说,COPY是首选。这是因为它比ADD更透明。COPY仅支持将本地文件基本复制到容器中,而ADD具有一些不明显的功能(如仅本地的tar提取和远程URL支持)。因此,ADD的最佳用途是将本地tar文件自动提取到图像中,如ADD rootfs.tar.xz/中所示。

更多:编写Dockerfile的最佳实践

ADD和COPY都具有将文件和目录从源复制到目标的相同功能,但ADD具有额外的文件提取和URL文件提取功能。最佳做法是仅在复制操作中使用COPY,避免在许多领域使用ADD。该链接将通过一些简单的示例解释dockerfile中COPY和ADD之间的区别

如果您有foo.tar.gz文件,请比较以下命令。ADD命令创建的层比COPY命令少,并且在推送docker图像时节省了大量的网络流量。

ADD foo.tar.gz /
COPY foo.tar.gz /
RUN tar -zxvf foo.tar.gz
RUN rm -rf foo.tar.gz

从Docker文档:https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/#add-或复制

“虽然ADD和COPY在功能上相似,但一般来说,COPY是首选。这是因为它比ADD更透明。COPY仅支持将本地文件复制到容器中的基本功能,而ADD具有一些功能(如仅本地tar提取和远程URL支持)这不是立即显而易见的。因此,ADD的最佳用途是将本地tar文件自动提取到图像中,如ADD rootfs.tar.xz/中所示。

如果您有多个Dockerfile步骤使用上下文中不同的文件,请单独复制它们,而不是一次复制所有文件。这将确保只有在特定需要的文件发生更改时,每个步骤的构建缓存才会失效(强制重新运行该步骤)。

例如:

 COPY requirements.txt /tmp/
 RUN pip install --requirement /tmp/requirements.txt
 COPY . /tmp/

与放置COPY相比,RUN步骤的缓存无效次数更少/tmp/之前。

因为图像大小很重要,所以强烈不建议使用ADD从远程URL获取包;您应该改用curl或wget。这样,您就可以删除提取后不再需要的文件,并且不必在图像中添加另一层。例如,您应该避免做以下事情:

 ADD http://example.com/big.tar.xz /usr/src/things/
 RUN tar -xJf /usr/src/things/big.tar.xz -C /usr/src/things
 RUN make -C /usr/src/things all

相反,请执行以下操作:

 RUN mkdir -p /usr/src/things \
     && curl -SL htt,p://example.com/big.tar.xz \
     | tar -xJC /usr/src/things \
     && make -C /usr/src/things all

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