ADD 仅自动解压构建上下文内的 .tar、.tar.gz/.tgz、.tar.bz2、.tar.xz(Docker 18.06+)和 .zip(Linux 宿主机有效)五类本地归档文件,其余如 .7z、.rar 等均不支持解压。

Dockerfile 中的 ADD 指令在遇到本地压缩文件(如 .tar.gz、.tar、.tgz、.zip)时,会自动解压并复制内容到镜像中——但这个行为有明确限制,仅对构建上下文内的本地文件生效,且不支持远程 URL 或非标准格式(如 .7z、.rar)。
哪些压缩格式会被 ADD 自动解压?
ADD 仅对以下格式的本地归档文件触发自动解压(要求文件在构建上下文中,且未指定目标为目录末尾带 /):
-
.tar(纯 tar 包) -
.tar.gz或.tgz .tar.bz2-
.tar.xz(Docker 18.06+ 支持) -
.zip(注意:仅 Linux 宿主机上构建时可用;Windows/macOS 宿主机构建可能失败或跳过解压)
⚠️ 不支持:.7z、.rar、.gz(单独 gzip 文件)、.bz2、.xz(非 tar 封装)等。这些会被当作普通文件复制,不会解压。
ADD 解压行为的常见陷阱
自动解压看似方便,但容易引发意料外的问题:
-
路径覆盖风险:若压缩包内含绝对路径(如
/etc/config.conf),ADD 会按原路径提取,可能覆盖镜像已有文件;建议压缩包使用相对路径打包。 - 权限丢失:解压后文件权限通常为默认 644/755,原始压缩包中的特殊权限(如 setuid)或属主信息不会保留。
-
ADD vs COPY 混用误区:如果目标路径以
/结尾(如ADD app.tar.gz /app/),Docker 仍会解压;但若写成ADD app.tar.gz /app(无结尾斜杠),则解压到/app目录下(即创建/app并放入内容),而非覆盖/app本身。 - 无法控制解压逻辑:不能跳过某些文件、不能指定编码、不能处理损坏包——出错直接构建失败。
推荐替代方案:显式解压更可控
为避免隐式行为带来的不确定性,生产环境建议用 COPY + RUN 组合代替 ADD 自动解压:
- 对
.tar.gz:COPY app.tar.gz /tmp/ && RUN tar -xzf /tmp/app.tar.gz -C /app && rm /tmp/app.tar.gz - 对
.zip:COPY app.zip /tmp/ && RUN unzip /tmp/app.zip -d /app && rm /tmp/app.zip - 需要保留权限或过滤文件时,可在
RUN中加入--same-permissions、--exclude等参数。
这样写法清晰、可调试、兼容所有平台,也便于添加校验(如先 sha256sum 验证再解压)。
一句话验证方法
快速测试某压缩包是否会被 ADD 解压:在 Dockerfile 中写一行 ADD test.xxx /dest/,执行 docker build -t test .,然后 docker run --rm -it test ls -l /dest 查看内容。若看到的是解压后的文件列表,说明支持;若只看到 test.xxx 文件本身,说明未触发解压。

















