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/

其他回答

从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。"

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

实例

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

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

实例

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

如果要将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仅使用一层。

从Docker文档:

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

更多:编写Dockerfile的最佳实践

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