Dockerfile中COPY和ADD命令的区别

Dockerfile中COPY和ADD命令的区别

技术背景

在创建Dockerfile时,有两个命令可用于将文件或目录复制到容器中,即ADDCOPY。虽然它们在功能范围上有细微差异,但本质上执行的是相同的任务。ADD命令是Docker平台推出以来就存在的,而COPY命令是由于ADD的一些功能问题后续引入的。

实现步骤

ADD命令

ADD命令的基本语法为:

1
ADD <src> … <dest>

它将文件或目录复制到指定容器的文件系统中。其中<src>是要复制的源,<dest>是存储的目标位置。

  • 若源是本地文件或目录,ADD会复制其中的所有内容(包括文件系统元数据)。例如:
1
ADD /source/file/path  /destination/path
  • ADD还可以从URL复制文件。例如:
1
ADD http://source.file/url  /destination/path
  • 对于本地存储的压缩文件(如.tar.gz.tar.xz等),ADD会自动将其内容提取到指定的目标位置。例如:
1
ADD source.file.tar.gz /temp

COPY命令

COPY命令的基本语法为:

1
COPY <src> … <dest>

它仅用于将本地存储的文件或目录以现有格式复制到指定位置,不处理压缩文件的提取,也不能使用URL复制外部文件。例如:

1
COPY /source/file/path  /destination/path 

核心代码

使用COPY复制并解压文件

1
2
3
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复制并解压文件

1
ADD resources/jdk-7u79-linux-x64.tar.gz /usr/local/

最佳实践

  • 优先使用COPY:如果只是简单地将本地文件或目录复制到构建上下文中,应始终使用COPY,因为它比ADD更透明。例如:
1
2
3
COPY requirements.txt /tmp/
RUN pip install --requirement /tmp/requirements.txt
COPY . /tmp/

这样可以确保每个步骤的构建缓存仅在特定所需文件更改时才失效。

  • 避免使用ADD下载远程包:由于镜像大小很重要,强烈建议不要使用ADD从远程URL获取包,而应使用curlwget。例如:
1
2
3
4
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提取本地压缩文件ADD的最佳用途是将本地tar文件自动提取到镜像中。例如:
1
ADD rootfs.tar.xz /

常见问题

  • COPY不支持URL源COPY命令不支持使用URL作为<src>
  • COPY不处理压缩文件COPY不会自动解压压缩文件,而是将其原样复制。对于instruction <src> <dest>,如果<src>是tar压缩文件且<dest>不以斜杠结尾,ADD会将<dest>视为目录并解压<src>到其中,而COPY会将<dest>视为文件并将<src>写入其中。
  • COPY支持多阶段构建:从Docker 17.05开始,COPY可以使用--from标志在多阶段构建中从先前的构建阶段复制工件到当前构建阶段。例如:
1
COPY --from=builder /app /app

Dockerfile中COPY和ADD命令的区别
https://119291.xyz/posts/2025-05-12.dockerfile-copy-vs-add-commands/
作者
ww
发布于
2025年5月12日
许可协议