ADD 与 COPY 差异
ADD 和 COPY 都用于拷贝文件到镜像,但功能有差异,下面梳理其区别。
COPY 指令
仅拷贝文件
dockerfile
# 基本用法
COPY package.json /app/
# 支持通配符
COPY *.conf /etc/nginx/
# 目录递归拷贝
COPY src/ /app/src/
# 多个文件
COPY file1.txt file2.txt /app/
COPY 行为可预测,仅拷贝文件到镜像,不执行额外操作。
ADD 指令
额外功能
ADD 除了拷贝功能外,还有两个额外特性:
1. 自动解压 tar 包
dockerfile
# ADD 自动解压 tar.gz、tar.bz2、tar.xz
ADD app.tar.gz /app/
# COPY 不解压,保留为文件
COPY app.tar.gz /app/
RUN tar -xzf /app/app.tar.gz -C /app/ && rm /app/app.tar.gz
2. 远程 URL 下载
dockerfile
# ADD 从 URL 下载文件
ADD https://example.com/file.txt /app/
# COPY 不支持 URL
对比表格
| 对比项 | COPY | ADD |
|---|---|---|
| 拷贝文件 | ✅ | ✅ |
| 自动解压 tar | ❌ | ✅ |
| 远程 URL 下载 | ❌ | ✅ |
| 行为可预测 | ✅ | ⚠️ |
| 推荐度 | ✅ 推荐 | ⚠️ 谨慎 |
最佳实践
优先使用 COPY
dockerfile
# 推荐:明确行为
COPY package.json /app/
COPY src/ /app/src/
ADD 仅在需要时使用
dockerfile
# 场景1:解压 tar 包
ADD app.tar.gz /app/
# 场景2:下载远程文件(但建议用 RUN wget/curl)
ADD https://example.com/config.yml /app/
# 更好的做法(明确控制)
RUN wget -O /app/config.yml https://example.com/config.yml
实际示例
错误做法
dockerfile
# 不推荐:ADD 行为不明确
ADD app.tar.gz /app/
ADD config.yml /app/
正确做法
dockerfile
# 推荐:COPY 用于常规拷贝
COPY config.yml /app/
# ADD 仅在需要解压时使用
ADD app.tar.gz /app/
# 或者使用 RUN 明确控制
RUN curl -sL https://example.com/app.tar.gz | tar -xz -C /app/
缓存影响
dockerfile
# COPY 利用缓存(文件未变则跳过)
COPY . /app/
# ADD 也利用缓存,但 URL 内容变化会破坏缓存
ADD https://example.com/file.txt /app/
权限与属主
dockerfile
# COPY 保留属主(以 root 运行)
COPY app.py /app/ # 属主 root:root
# 修改属主
COPY --chown=node:node app.py /app/
# ADD 同样支持
ADD --chown=node:node app.tar.gz /app/
要点总结
- COPY 仅拷贝文件,行为可预测,推荐使用
- ADD 额外支持自动解压 tar 包和远程 URL 下载
- 优先使用 COPY,仅在需要解压 tar 包时使用 ADD
- 远程 URL 下载建议用 RUN wget/curl 更明确控制
- ADD 行为不明确,可能造成镜像层混乱,谨慎使用
📝 发现内容有误?点击此处直接编辑