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

COPY <src> <dest>

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

ADD <src> <dest>

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


当前回答

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

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

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

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

其他回答

docker build -t {image name} -v {host directory}:{temp build directory} .

这是将文件复制到图像中的另一种方法。-v选项临时创建一个在构建过程中使用的卷。

这与其他卷不同,因为它仅为生成装载主机目录。可以使用标准cp命令复制文件。

此外,像curl和wget一样,它可以在命令堆栈中运行(在单个容器中运行),而不必乘以图像大小。ADD和COPY不可堆叠,因为它们在独立的容器中运行,并且在其他容器中执行的文件上的后续命令将使图像大小倍增:

通过这样设置选项:

-v /opt/mysql-staging:/tvol

以下内容将在一个容器中执行:

RUN cp -r /tvol/mysql-5.7.15-linux-glibc2.5-x86_64 /u1 && \
    mv /u1/mysql-5.7.15-linux-glibc2.5-x86_64 /u1/mysql && \

    mkdir /u1/mysql/mysql-files && \
    mkdir /u1/mysql/innodb && \
    mkdir /u1/mysql/innodb/libdata && \
    mkdir /u1/mysql/innodb/innologs && \
    mkdir /u1/mysql/tmp && \

    chmod 750 /u1/mysql/mysql-files && \
    chown -R mysql /u1/mysql && \
    chgrp -R mysql /u1/mysql

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

副本:

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仅支持本地焦油提取。除此之外,COPY将使用三层,但ADD仅使用一层。

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

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

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

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

您应该查看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处理。

直接从源代码引用。