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

COPY <src> <dest>

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

ADD <src> <dest>

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


当前回答

ADD指令从本地或远程源复制文件或文件夹,并将其添加到容器的文件系统中。它用来复制本地文件,这些文件必须在工作目录中。ADD指令将本地.tar文件解包到目标映像目录。

实例

ADD http://someserver.com/filename.pdf /var/www/html

COPY从工作目录复制文件并将其添加到容器的文件系统中。无法使用Dockerfile指令的URL复制远程文件。

实例

COPY Gemfile Gemfile.lock ./
COPY ./src/ /var/www/html/

其他回答

关于这一点,有一些官方文档:编写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。

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

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

由于Docker 17.05 COPY在多阶段构建中与--from标志一起使用,所以可以将工件从先前的构建阶段复制到当前的构建阶段。

从文档中

可选地,COPY接受一个标志--from=<name|index>,该标志可用于将源位置设置为将使用的前一个生成阶段(使用from..AS创建),而不是用户发送的生成上下文。

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

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

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

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

如果您有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