应优先使用 COPY,因其语义清晰、缓存友好且安全可控;仅在需自动解压本地 tar 包时才用 ADD;RUN 专用于构建阶段执行命令,不可替代文件复制功能。

RUN、COPY 和 ADD 是 Dockerfile 中最常被混用的三个指令,但它们职责完全不同:RUN 执行命令,COPY 专注复制本地文件,ADD 则多了一层“自动解压 + 支持 URL”的能力——正因如此,多数场景下 COPY 更安全、更可控。
RUN:构建时执行命令,影响镜像层和依赖
RUN 在镜像构建阶段运行 shell 命令,每条 RUN 指令都会生成一个新镜像层。它适合安装软件、编译代码、修改配置等需要执行逻辑的操作。
- 建议合并多个 RUN 命令(用 && 连接),减少镜像层数,避免中间层残留无用文件
- 避免在 RUN 中使用 apt-get install 后不加 -y 或不清理缓存(如 apt-get clean),否则会增大镜像体积
- 敏感操作(如下载密钥、写入临时凭证)不要放在 RUN 里,防止被意外暴露在镜像历史中
COPY:推荐的文件复制方式,语义清晰、缓存友好
COPY 只做一件事:把构建上下文中的文件或目录,原样复制到镜像指定路径。它不处理 URL,不解压 tar 包,行为可预测。
- 优先用于复制源码、配置文件、静态资源等常规内容
- 支持 --chown 参数直接设置文件所有者,比如 COPY --chown=node:node app/ /home/node/app/
- 缓存机制基于文件内容哈希,内容不变则跳过复制,后续层可复用缓存(利于分步优化,如先 COPY package.json 再 RUN npm install)
- 通配符可用(如 COPY *.js /app/),但注意匹配范围是否符合预期
ADD:功能更强,但容易误用,仅在必要时启用
ADD 能做 COPY 的所有事,还额外支持两种能力:从远程 URL 下载文件、自动解压本地 tar 归档(gzip/bzip2/xz 等格式)。
- 只有真正需要自动解压 tar 包(且确认该归档不会被意外覆盖或污染路径)时才用 ADD
- 不建议用 ADD 下载远程文件(如 ADD https://example.com/file.zip /tmp/)——这会让构建不可重现、变慢,且无法清理下载产物;应改用 RUN + curl/wget + rm 组合
- 若误将 keep_this_archive.tar.gz 当作普通文件复制,ADD 会静默解压,导致文件结构混乱,而 COPY 会忠实保留原文件
- ADD 不支持 --chown,如需设权限,得靠后续 RUN chown,增加一层且易遗漏
一句话选型指南
要复制?用 COPY。要解压本地 tar?考虑 ADD。要下载网络文件?别用 ADD,改用 RUN + curl。要执行命令?只用 RUN。不复杂但容易忽略——清晰分工,才是稳定构建的基础。


















