在 Dockerfile 中,ADD 和 COPY 都用于将文件或目录从构建上下文(通常是 Dockerfile 所在的目录)复制到 Docker 镜像中,但它们有一些关键区别:
1. COPY 指令
COPY 主要用于复制本地文件或目录到容器的指定路径。
📌 语法
dockerfile
COPY <源路径> <目标路径>
📌 特性
✅ 仅支持复制本地文件或目录 (不能从远程 URL 复制)。
✅ 不会自动解压 .tar 压缩包 (需要手动 RUN tar -xvf)。
✅ 适用于简单的文件复制操作。
📌 示例
dockerfile
COPY index.html /usr/share/nginx/html/
- 这会将
index.html文件复制到/usr/share/nginx/html/目录下。
dockerfile
COPY src/ /app/
- 这会将
src/目录的所有内容复制到/app/目录下。
2. ADD 指令
ADD 比 COPY 更强大,除了能复制文件,它还能处理远程 URL 下载 和自动解压 .tar 压缩包。
📌 语法
dockerfile
ADD <源路径> <目标路径>
📌 特性
✅ 可以复制本地文件和目录 (与 COPY 相同)。
✅ 支持远程 URL 下载 (COPY 不支持)。
✅ 自动解压 .tar 文件 (但不会解压 .zip)。
✅ 适用于需要自动解压或者拉取远程资源的场景。
📌 示例
dockerfile
ADD example.tar.gz /app/
ADD自动解压example.tar.gz到/app/。
dockerfile
ADD https://example.com/sample.txt /app/sample.txt
ADD会从 URL 下载sample.txt并存储到/app/sample.txt。
3. ADD vs COPY 选择
| 特性 | ADD |
COPY |
|---|---|---|
| 复制本地文件/目录 | ✅ | ✅ |
| 支持远程 URL 下载 | ✅ | ❌ |
自动解压 .tar 文件 |
✅ | ❌ |
| 适用于文件复制 | ❌ | ✅ 更推荐 |
📌 何时使用 COPY?
- 推荐使用
COPY,因为它更简单、明确,避免ADD可能带来的副作用(如意外解压)。
📌 何时使用 ADD?
- 需要自动解压
.tar.gz文件到指定目录时。 - 需要从远程 URL 下载文件 时(尽管更推荐
RUN wget或RUN curl)。
4. 最佳实践
- 尽量使用
COPY,因为ADD的功能更复杂,可能会导致意外行为(如.tar自动解压)。 - 如果需要解压
.tar,可以手动使用RUN tar -xvf,避免ADD带来的不可控行为。 - 如果需要下载远程文件,更推荐
RUN wget或RUN curl,而不是ADD,这样可以提高 Docker 层的可复用性。
📌 推荐方式
dockerfile
# 推荐方式 1: 复制本地文件
COPY myfile.txt /app/
# 推荐方式 2: 下载远程文件(避免用 ADD)
RUN wget -O /app/sample.txt https://example.com/sample.txt
# 推荐方式 3: 解压 .tar 文件(避免用 ADD)
COPY example.tar.gz /app/
RUN tar -xzf /app/example.tar.gz -C /app/ && rm /app/example.tar.gz
总结
✅ COPY 更推荐 ,因为它只做文件复制,避免 ADD 的额外功能带来意外行为。
✅ ADD 适用于特殊场景 ,如自动解压 .tar.gz 或远程下载(但 RUN wget/curl 更灵活)。
✅ Docker 官方推荐优先使用 COPY,除非 ADD 的特性确实有用。