bigywater.tech
Docker · 9

COPY 与 ADD:自动解压和远程 URL 的差别

Dockerfile 最佳实践常说“能用 COPY 就不要用 ADD”。ADD 到底多做了什么?这篇用同一组本地压缩包和一个本地 HTTP 服务逐项验证:自动解压的范围、权限与属主、远程 URL 的行为,以及 --checksum 能不能挡住被篡改的下载。

tar、tar.gz 解压,zip 不解压
ADD 对本地压缩包的处理
0600 root
ADD 远程 URL 下载的文件的权限与属主
digest mismatch
ADD --checksum 摘要不匹配时的构建错误

ADD 的“多余”功能一:解压

实测 · 本机执行输出
  构建退出码 0
  [COPY 的结果 /copy]
  /copy
  /copy/pack.tar
  /copy/pack.tar.gz
  /copy/pack.zip
  [ADD 的结果 /add]
  /add
  /add/hello
  /add/hello/a.txt
  /add/hello/b.txt
  /add/pack.zip

本地的 pack.tar 与 pack.tar.gz 被 ADD 自动解压到目标目录(得到 /add/hello/a.txt 等),pack.zip 不会;COPY 三者都原样复制。所以“把压缩包放进镜像”用 COPY,“展开一个 tar”才用 ADD——而且最好明确写出来,避免有人把 tar 当成普通文件复制却被悄悄解压。

目录与权限

实测 · 本机执行输出
  -rw-r----- 1 0 0 2 Oct 10 07:19 /a/dir/x.txt
  -rw-r----- 1 0 0 2 Oct 10 07:19 /c/dir/x.txt
  -rwxr-xr-x 1 0 0 18 Oct 10 07:19 /c/run.sh
  -rw------- 1 1000 1000 18 Oct 10 07:19 /c/run600.sh
  COPY dir 与 ADD dir 的内容完全相同

ADD dir 与 COPY dir 得到完全相同的内容(diff -r 验证)。权限默认保留源文件的,COPY --chmod、--chown 可以显式指定,实验里得到 -rw------- 与 1000:1000。

ADD 的多余功能二:远程 URL

实测 · 本机执行输出
  构建退出码 0;
  total 8
  -rw------- 1 0 0 1200 Oct 10 07:19 data.txt
  -rw------- 1 0 0 132 Oct 10 07:19 remote.tar.gz
  ---
   1f 8b 08 08
  [--checksum 正确] 退出码 0
  [--checksum 错误] 退出码 1;#5 [2/2] ADD --checksum=sha256:0000000000000000000000000000000000000000000000000000000000000000 http://host.docker.internal:9700/data.txt /bad.txt | #5 ERROR: digest mismatch sha256:457f243108297082e9e2d67120646e041f1b5fc7162b8210ebce759dbe47dfff: sha256:00000

URL 由守护进程(构建器)去下载,不是客户端。下载的文件权限是 0600、属主 root,压缩包不会被解压(开头是 gzip 的 1f 8b)。加 --checksum=sha256:… 可以校验内容,写错摘要构建以 digest mismatch 失败。本文的 URL 指向宿主机上的本地服务,没有测真实的外网下载。

分步演示

COPY 与 ADD
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Docker Desktop(Engine 29.8.2,容器跑在 Docker Desktop 自带的 Linux 虚拟机里,内核与宿主机的 macOS 不同);镜像为 linux/arm64;需要看虚拟机内部时用特权容器 + nsenter;计时用 time / date +%s%N,数字每次运行会有小幅抖动。压缩包由 Python tarfile / zipfile 生成;URL 指向宿主机上用 Python 起的 HTTP 服务(通过 host.docker.internal 访问);结果通过在构建出的镜像里 find / ls / od 观察;每种情形一次;实验后已删除所有镜像和临时文件
    • 没有验证:git URL 作为 ADD 源、真实互联网上的 ADD、ADD 解压 tar.xz / tar.bz2 / tar.zst、符号链接与硬链接在 tar 里的处理、ADD 缓存键对远程内容变化的反应
    京ICP备2026067502号-1京公网安备11010502063487号