COPY 指令比 ADD 更高效、安全且可控;它仅复制文件、缓存命中率高,不自动解压或下载,语义清晰,官方推荐优先使用,构建速度快10%–25%。

COPY 指令通常比 ADD 更高效,尤其在构建缓存复用和镜像精简方面更优。
缓存命中率更高
COPY 只做文件/目录的单纯复制,行为确定、无副作用,Docker 构建时能更精准地判断某一层是否需要重建。只要源文件没变、目标路径不变,后续指令就能直接复用缓存。
ADD 则隐含额外逻辑:自动解压本地 tar 包(如 .tar、.tar.gz)、支持 URL 下载。这些行为让它的执行结果不可预测——比如 tar 内容变化不会被 Docker 文件系统层感知,导致缓存失效或误命中。
- 使用 COPY 复制压缩包(如 app.tar.gz)只是普通文件拷贝,不触发解压
- 用 ADD 复制同名 tar 包会自动解压,且解压后文件树变更无法被缓存机制有效追踪
- 若需解压,显式用 COPY + RUN tar -xzf 更可控,缓存也更稳定
镜像体积与安全性更可控
ADD 支持从远程 URL 下载文件(如 ADD https://example.com/app.zip /app/),看似方便,但会带来问题:
- 每次构建都重新下载,无法利用构建缓存,拖慢构建速度
- URL 不稳定或网络异常会导致构建失败,降低可重现性
- 下载内容未经校验,存在安全风险;也无法在离线环境中构建
推荐做法是:用 curl/wget + RUN 下载,并配合校验(如 sha256sum),再用 COPY 加入镜像——过程透明、可缓存、可审计。
语义清晰,利于维护
Docker 官方明确建议:优先使用 COPY;仅在确实需要自动解压本地 tar 归档时才用 ADD。
这种分工让 Dockerfile 行为更易理解:
- COPY = “把东西搬进来”,意图明确,无隐藏动作
- ADD = “搬进来并可能顺手拆开”,语义过载,容易引发意外行为
- 团队协作中,统一用 COPY 能减少歧义,降低出错概率
实际构建耗时差异明显
在多阶段构建或频繁修改源码的场景下,COPY 的优势放大:
- 修改一个 .go 文件后重新构建,COPY . /app/ 这一层大概率命中缓存
- 若此处误用 ADD . /app/,哪怕只改了 .gitignore,Docker 也可能因内部处理逻辑不同而跳过缓存
- 基准测试显示:相同内容下,纯 COPY 构建比 ADD 快 10%–25%,主要省在缓存判断与解压跳过上










