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

COPY <src> <dest>

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

ADD <src> <dest>

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


当前回答

从Docker文档:

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

更多:编写Dockerfile的最佳实践

其他回答

您应该查看ADD和COPY文档,以了解其行为的更详细描述,但简而言之,主要区别在于ADD可以比COPY做得更多:

ADD允许<src>作为URL参考以下评论,ADD文件指出:

如果是公认的压缩格式(标识、gzip、bzip2或xz)的本地tar存档,则将其解压缩为目录。来自远程URL的资源不会解压缩。

注意,编写Dockerfile的最佳实践建议在不需要ADD魔力的地方使用COPY。否则,当您打算将keep_this_archive_intact.tar.gz复制到容器中时,您(因为您必须查找这个答案)可能会感到惊讶,但相反,您将内容喷到文件系统中。

副本为

与“ADD”相同,但没有tar和远程URL处理。

直接从源代码引用。

假设您有一个tar文件,您想在将其放入容器后解压缩它,然后删除它,您可以使用COPY命令执行此操作。但各种命令可能是1)将tar文件复制到目标,2)。解压缩,3)删除tar文件。如果您分三步完成此操作,则在每一步之后都会创建一个新图像。您可以使用&一步到位,但这很麻烦。

但是你使用了ADD,那么Docker会为你处理所有的事情,只会创建一个中间映像。

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

关于这一点,有一些官方文档:编写Dockerfile的最佳实践

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

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

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