优先使用COPY而非ADD;COPY仅原样复制文件,行为稳定可预测,支持多阶段构建和权限控制,而ADD会自动解压本地压缩包并支持URL下载,但易导致不可重现构建和意外覆盖。

COPY只做复制,ADD额外带“魔法”
COPY 的作用非常明确:把构建上下文里的文件或目录原封不动地复制进镜像,不做任何解释、不下载、不解压。它就像一个老实的搬运工,指哪搬哪。
ADD 表面看也是搬运,但暗藏两个特殊能力:一是遇到本地 .tar、.tar.gz、.tar.xz 等格式压缩包时,会自动解压到目标路径;二是支持直接写 URL,比如 ADD https://example.com/app.zip /tmp/,会先下载再存入镜像(但不会解压)。
行为可预测性差异明显
COPY 的行为稳定、透明,每次构建效果一致,适合长期维护和团队协作。只要源文件没变,缓存就复用,构建快且可靠。
ADD 则容易“出其不意”:
- 如果误把
data.tar.gz用 ADD 复制到已有内容的目录,它会自动解压并覆盖同名文件,可能破坏原有结构 - 用 URL 下载时,构建过程依赖网络,失败即中断,还可能因远程文件变更导致镜像不可重现
- 自动解压逻辑只对本地压缩包生效,URL 文件不触发解压——这种不一致也增加了理解成本
官方推荐与真实适用场景
Docker 官方文档明确建议:99% 的情况优先用 COPY。它的语义清晰、功能专注,是构建可维护 Dockerfile 的基石。
ADD 的合理使用场景其实非常有限:
- 需要快速解压一个官方提供的 rootfs 压缩包(如
ADD ubuntu-minimal-cloudimg-amd64-root.tar.gz /) - 迁移老旧项目,且无法修改已有 ADD 逻辑
- 极少数 CI 场景中需临时拉取固定版本的二进制包(但仍建议改用 RUN + curl/wget 更可控)
多阶段构建与高级选项实践
在现代 Docker 工作流中,COPY 的优势进一步放大:
- 支持
--from=builder跨阶段复制,这是多阶段构建传递产物的标准方式,ADD 不支持 - COPY 支持
--chown和--chmod(17.09+,启用 BuildKit 后),能精细控制权限,避免容器内权限问题 - 若真要解压,更推荐显式拆解:先 COPY 压缩包,再 RUN tar 解压并清理,逻辑清晰、便于调试
例如:
COPY app.tar.gz /tmp/<br>RUN tar -xzf /tmp/app.tar.gz -C /app && rm /tmp/app.tar.gz
这比一行 ADD 更安全、更易审计、也更容易加日志或校验步骤。








