Dockerfile中的`COPY`和`ADD`命令有什么区别?

Steve 1991 docker dockerfile

是什么之间的差异COPY,并ADD在Dockerfile命令,当我将使用一个比其他?

COPY <src> <dest>

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

ADD <src> <dest>

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

icecrime.. 1992

您应该查看ADDCOPY记录其行为的详尽描述,但简而言之,主要区别在于它ADD可以做的不仅仅是COPY:

  • ADD允许<src>成为一个URL
  • 如果ADD参数COPY是具有已识别压缩格式的存档,则将对其进行解压缩

请注意,编写Dockerfiles最佳实践建议使用ADD不需要魔法的地方keep_this_archive_intact.tar.gz.否则你(因为你必须查找这个答案)有可能会在你想要复制ADD到容器中时感到惊讶,而是将内容喷到你的文件系统上.

  • 只想澄清一些事情:使用带有URL的ADD到.tar.gz不要将存档提取到文件系统(我现在仔细检查以确定它已经确认) (47认同)
  • 这是必不可少的信息,官方Dockerfile参考没有通过这种方式澄清差异是一种犯罪. (26认同)
  • @SantoshKumarArjunan:Docker文档陈述了有关ADD和自动tar提取的以下内容:`如果&lt;src&gt;是采用公认压缩格式(身份,gzip,bzip2或xz)的本地tar存档,则将其解压缩为目录。不会解压缩来自远程URL的资源。`[Docker ADD](https://docs.docker.com/engine/reference/builder/#add) (3认同)

caike.. 426

COPY

与"ADD"相同,但没有tar和远程URL处理.

直接从源代码引用.

  • 我是否正确看到了这一点:`ADD`也**创建了不存在的目录**.所以,尽管在整个帖子中有点气馁,但它比'COPY'有**优势**因为你不必运行`mkdir`并节省一些打字 (9认同)
  • 多么明显!毕竟,源代码是文档。&lt;/ snark&gt; (5认同)

小智.. 135

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

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

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

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

  • Docker说更喜欢`COPY`,因为它更透明.来自[Docker文件最佳实践](https://docs.docker.com/articles/dockerfile_best-practices/#add-or-copy)(2014-12-15):`虽然ADD和COPY在功能上相似,但一般来说说,COPY是首选.那是因为它比ADD更透明.COPY仅支持将本地文件基本复制到容器中,而ADD具有一些不是很明显的功能 (16认同)
  • 另请参见[8月份提交](https://github.com/wking/dockerfile/commit/707be173773a520571056001fec2a27da2e72235),其中[Docker文件为Docker本身从ADD切换到COPY](https://github.com/docker/docker /斑点/主/ Dockerfile#L113) (2认同)

eddd.. 113

来自Docker文档:

添加或复制

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

更多:编写Dockerfiles的最佳实践


小智.. 39

如果要将xx.tar.gz添加到/usr/local容器中,请将其解压缩,然后删除无用的压缩包.

对于COPY:

COPY resources/jdk-7u79-linux-x64.tar.gz /tmp/
RUN tar -zxvf /tmp/jdk-7u79-linux-x64.tar.gz -C /usr/local
RUN rm /tmp/jdk-7u79-linux-x64.tar.gz

对于ADD:

ADD resources/jdk-7u79-linux-x64.tar.gz /usr/local/

ADD支持仅本地tar提取.除此之外,COPY将使用三层,但ADD仅使用一层.

  • 任何理由不仅仅是两层?`RUN tar -zxvf /tmp/jdk-7u79-linux-x64.tar.gz -C/usr/local && rm/tmp/jdk-7u79-linux-x64.tar.gz` (2认同)

jhpg.. 14

来自Docker文档:https: //docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/#add-or-copy

"尽管ADD和COPY在功能上相似,但一般来说,COPY是首选.这是因为它比ADD更透明.COPY仅支持将本地文件基本复制到容器中,而ADD具有一些功能(如仅限本地的tar提取和因此,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."


JSON C11.. 10

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

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

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

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


小智.. 5

来源:https : //nickjanetakis.com/blog/docker-tip-2-the-difference-between-copy-and-add-in-a-dockerile

COPY和ADD都是具有相似用途的Dockerfile指令。它们使您可以将文件从特定位置复制到Docker映像中。

COPY接收src和目的地。它仅允许您从主机(构建Docker映像的机器)的本地文件或目录中复制到Docker映像本身。

ADD也允许您执行此操作,但是它还支持其他2个来源。首先,您可以使用URL代替本地文件/目录。其次,您可以将tar文件从源直接提取到目标中

当您想将本地tar文件提取到Docker映像中的特定目录中时,ADD的有效用例。

如果要将本地文件复制到Docker映像,请始终使用COPY,因为它更加明确。