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

创建 Dockerfile 时,可以使用两个不同的命令来构建上下文。构建上下文意味着包括您希望从本地计算机获取的文件和目录,这些文件和目录在创建时位于容器中。这些文件可能是您本地计算机中的目录、您要从中下载文件的 URL,或者您希望按原样或在解压缩 tarball 文件后包含的压缩 tarball 文件。

我们可以使用两种不同的指令将本地机器中构建上下文中的文件添加到 Docker 容器中。这些是 COPY 和 ADD 指令。尽管它们执行的任务几乎相同,但是它们的工作方式略有不同。所以,这里的问题是为什么我们有两个不同的命令来执行相同的工作,我们应该使用哪一个?

在本文中,我们将讨论相同的内容。因此,事不宜迟,让我们讨论 ADD 和 COPY 指令的用例。

添加指令

我们在 Dockerfile 中使用的 ADD 指令是一条相对较旧的指令,从一开始就与 Docker 一起使用。ADD 指令可以做的不仅仅是从本地主机复制目录或文件。我们可以使用 ADD 指令从外部链接/URL(如 Github、Bitbucket 等)中提取文件或目录。 ADD 指令还可用于提取压缩文件,如存档或 tarball 文件。但是,有时,如果您实际上不想提取档案,则可能会导致问题。

ADD 指令的语法是 -

$ ADD <source path> <destination path>

ADD 指令的一些重要用例是 -

  • 将文件和目录从本地机器复制到图像。

例如,如果我们想简单地将本地主机系统中 /home/user/Dekstop/app 目录中的文件复制到 Docker 镜像中的 /app 目录中,我们可以将此指令嵌入到 Dockerfile 中-

$ ADD /home/user/Desktop/app /app

在这种情况下,守护进程只将源目录的内容复制到目标目录,包括元数据。由于我们没有提到尾部斜杠,它不会复制目录本身。

  • 提取本地存储的 tarball 文件。

ADD 指令还可用于提取具有以下格式的压缩 tarball 文件或存档 - bzip2、xz、gzip2。ADD 指令会自动提取在 Docker 容器的目标文件夹内创建的目录中的内容。比如我们想把sample.tar.gz文件解压到容器内部的/app目录下,可以使用如下命令。

$ ADD /home/user/sample.tar.gz /app

这与在我们的主机中提取 tarball 的 tarball 命令的操作完全相似。

  •  从 URL 下载目录或文件

ADD 指令的这一特性类似于 wget -P 命令的工作方式。当我们尝试构建 Docker 镜像时,我们可以使用 ADD 指令直接从给定的 URL 下载文件并将其存储在容器内的某个位置。这样做的命令是 -

$ ADD
https://www.asamplelink.com/test/sampledocuments/mysamplefile.pdf /app

当镜像构建完成后,我们可以在容器启动时访问这些文件。

复制指令

我们可以将 Dockerfile 中的 COPY 指令视为 ADD 指令的进化版本。创建 COPY 指令是为了消除 Docker 开发人员之间的混淆。COPY 指令的唯一功能是将文件从主机上的源目录复制到容器上的目标目录。如果我们将源文件称为 tarball 文件,它不会将其提取到容器中,而只是按原样复制它。

此外,COPY 指令不将 URL 参数作为源。使用 COPY 指令复制文件的语法是 -

$ COPY <source> <destination>

例子 -

$ COPY /home/user/sample/files /app

最后的想法!

总而言之,如果您希望简单地将文件和目录从本地主机复制到容器环境,建议您仅使用 COPY 指令。您必须尽可能避免使用 ADD 指令。如果你想解压或下载文件,你可以使用 RUN 指令和普通的 Linux 命令。

在本文中,我们讨论了如何使用 ADD 和 COPY Dockerfile 指令、它们的用例、两者之间的根本区别以及一些动手示例和命令。