首页/云/云与容器速查/Dockerfile ADD 指令
容器与 Docker106 条

Dockerfile ADD 指令

COPY 的增强版:额外支持本地 tar 自动解压与 URL 下载。除『确实需要解压 tar』外,一律优先 COPY——ADD 的隐式解压常让人意外。

云与容器速查云更新于 2026-10-13

Dockerfile ADD 是什么

ADD 是 COPY 的增强版:除了复制文件,它还会把本地 tar 包自动解开,也能从 URL 拉取文件。这种隐式行为是它最大的问题——写 ADD 的人常常只想要一次复制,结果得到一个解压后的目录结构,或者一个权限为 600、内容还没校验的下载文件。除非确实需要自动解压本地 tar,否则一律用 COPY,让每一步做了什么一眼可见。

基本信息

语法ADD [--chown=用户:组] [--chmod=权限] 源 目标
额外能力本地 tar 自动解压;支持从 URL 拉取文件
解压范围仅本地 tar 及其 gz、bz2、xz 压缩形式;zip 不解,远程 tar 也不解
URL 行为只下载不解压、不校验完整性、失败不自动重试,文件权限为 600
缓存行为URL 目标的内容变化不会让缓存失效,容易构建出旧内容的镜像
建议普通复制用 COPY,ADD 只用于明确的本地 tar 解压场景

典型使用场景

  • 解压官方发布的 tar 包到固定目录,如把服务端程序放进运行镜像
  • 把构建产物包解压到运行阶段,配合多阶段构建减少最终体积
  • 迁移历史 Dockerfile 时保持原有行为,先确认解压结果再做优化
  • 需要一次性拉取并解压时,改用 RUN 配合下载工具并校验校验和
  • 解压后需要指定属主与权限:用 --chown 明确,避免默认 root 属主

使用示例

使用示例
ADD app-2026.tar.gz /opt/app/   # 本地 tar.gz 自动解压到目标目录
ADD --chown=app:app assets/ /srv/assets/   # 指定解出的文件属主(较新版本)
ADD config.yaml /etc/app/config.yaml   # 普通文件:与 COPY 行为一致
ADD https://example.com/pack.tgz /tmp/   # 从 URL 下载,不会解压也不会校验
# 推荐替代:先校验再解压
# RUN curl -fsSL -o /tmp/p.tgz https://example.com/pack.tgz && echo "校验值  /tmp/p.tgz" | sha256sum -c - && tar -xzf /tmp/p.tgz -C /opt/app

COPY 与 ADD 对照

能力COPYADD
本地普通文件支持支持,行为一致
本地 tar 自动解压不支持支持 gz、bz2、xz 等形式
zip 压缩包不解也不解,落在镜像里的是压缩包
远程 URL不支持支持,但不校验、不解压、权限受限
缓存失效判断按本地内容URL 内容变化不会触发失效
URL 形式不校验完整性、失败不重试,属于典型的供应链风险入口:改用下载并校验校验和的做法,或把产物先放到构建上下文里。
远程 tar 不会被解压,这一点与本地 tar 的行为不同:需要解压时先在构建阶段下载,再用 RUN 解开。

易错点

  • 以为 ADD 能解压 zip 或远程 tar:两者都不解,落到镜像里的是压缩文件
  • tar 包里带顶层目录:解到目标路径后多出一层嵌套,启动脚本按原路径找不到文件
  • 用 ADD URL 代替正规下载:不校验校验和,构建结果不可复现
  • 解压后忽略属主与权限:文件属主为 root 或权限不符,应用启动即报权限错误
  • 把 ADD 与 COPY 混用来回改:行为不确定,review 时容易漏看隐式解压

数据来源与参考

  • Docker Docs:Dockerfile reference(ADD)

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌