Dockerfile中ADD与COPY的使用异同
文章目录
简要说明在使用Dockerfile构建镜像时,ADD与COPY指令的使用差异。
近期在使用Docker时,发现部分项目中采用Dockerfile来构建自定义镜像时存在COPY和ADD两条指令混用的情况,为了规范使用,基于网络上的相关资料,简要的对比总结了它们的差异,供后续参考。
对比
在Docker官网关于COPY指令的描述如下
The
COPYinstruction copies new files or directories from<src>and adds them to the filesystem of the container at the path<dest>.
关于ADD的描述如下
The
ADDinstruction copies new files, directories or remote file URLs from<src>and adds them to the filesystem of the image at the path<dest>.
从它们的描述可知,这两条指令的作用基本上类似,都是将特定文件或文件夹拷贝到镜像中,不同的是ADD指令还能从远程URL中拷贝文件并添加到镜像中。
继续查看对应的文档,在ADD的指令描述下有如下说明
If
<src>is a localtararchive in a recognized compression format (identity,gzip,bzip2orxz) then it’s unpacked as a directory. Resources from remote URLs aren’t decompressed. When a directory is copied or unpacked, it has the same behavior astar -x.
从中可知若要拷贝的本地文件属于tar系列的压缩文件,则会自动解压为对应的文件夹或文件,这是其相对于COPY的另一个显著的不同点。
关于它们更直观的对比说明,可在源文件中查看相应的备注:
// COPY foo /path
//
// Same as 'ADD' but without the tar and remote url handling.
func dispatchCopy(d dispatchRequest, c *instructions.CopyCommand) error {
// xxx
}
总结下来就是 COPY指令处理不能进行压缩文件和URL文件流的处理之外,其它功能与ADD指令类似。
验证
为了便于观察Dockerfile构建过程中的输出,可在构建指令中加入--progress=plain来查看输出的详细信息,类似如下
docker build --progress=plain --no-cache -t custom:v1.0 -f Dockerfile .
ADD指令
-
验证普通的文件拷贝
Dockerfile文件如下FROM ubuntu:18.04 RUN mkdir /home/lucumt WORKDIR /home/lucumt ADD test.sh /home/lucumt RUN ls /home/lucumt输出结果如下

-
验证URL文件流下载
Dockerfile文件如下1FROM ubuntu:18.04 RUN mkdir /home/lucumt WORKDIR /home/lucumt ADD https://nginx.org/download/nginx-1.0.15.tar.gz /home/lucumt RUN ls /home/lucumt输出结果如下,从中可以看出对于URL类型的文件,在
Dockerfile的构建过程中只会拷贝,不会解压缩
-
验证tar文件解压
Dockerfile文件如下FROM ubuntu:18.04 RUN mkdir /home/lucumt WORKDIR /home/lucumt ADD nginx-1.0.15.tar.gz /home/lucumt RUN ls /home/lucumt输出结果如下,可以看出对于从本地拷贝的
tar类型文件,Dockerfile构建过程中会默认进行解压缩
COPY指令
-
验证普通文件
Dockerfile文件内容如下FROM ubuntu:18.04 RUN mkdir /home/lucumt WORKDIR /home/lucumt COPY test.sh /home/lucumt RUN ls /home/lucumt输出结果如下

-
验证URL文件流下载
Dockerfile文件内容如下FROM ubuntu:18.04 RUN mkdir /home/lucumt WORKDIR /home/lucumt COPY https://nginx.org/download/nginx-1.0.15.tar.gz /home/lucumt RUN ls /home/lucumt输出结果如下,可看出由于
COPY指令不支持URL格式,构建过程会出错
-
验证tar文件解压
Dockerfile文件内容如下FROM ubuntu:18.04 RUN mkdir /home/lucumt WORKDIR /home/lucumt COPY nginx-1.0.15.tar.gz /home/lucumt RUN ls /home/lucumt输出结果如下,可看出此时对于本地压缩文件不会进行解压。

总结
官方推荐的是在不需要使用ADD指令的高级特性的场景下,优先使用COPY指令,其更直观也不会造成困惑。
假设对于一个新手来说,采用类似ADD nginx-1.0.15.tar.gz /home/lucumt进行构建后最后却得到的是一个解压文件,在不熟悉相关指令细节时会让人觉得很奇怪。
参考链接: