COPY 指令是什么
COPY 把构建上下文或前一构建阶段里的文件复制进镜像。它的实用价值集中在两点:一是能从多阶段构建的上一阶段取产物,二是与缓存机制强相关——被复制文件的内容一变,该层及其后的所有层全部失效,所以复制顺序直接决定构建快慢。
基本信息
| 语法 | COPY [--chown=用户:组] 源 目标 |
|---|---|
| 来源 | 构建上下文或其它阶段(--from=阶段名),不能拉取 URL |
| 缓存特性 | 源文件内容变化会让该层与后续层缓存全部失效 |
| 顺序优化 | 先复制依赖清单装依赖,再复制源码 |
| 归属设定 | --chown 在复制时指定属主,省掉一层 chown |
| 与 ADD 区别 | ADD 会解压本地压缩包并支持远程 URL,日常复制用 COPY |
与缓存的互动
| 变化点 | 缓存结果 | 建议 |
|---|---|---|
| 依赖清单变化 | 该层及之后全部重建 | 依赖更新频率低,放前面收益最大 |
| 只改业务源码 | 依赖层继续命中缓存 | 目标就是与源码解耦 |
| 上下文其他文件变化 | 命中该 COPY 的层失效 | 用 .dockerignore 缩小上下文 |
| 调整指令顺序 | 缓存需重新计算 | 顺序本身影响收益,改完要实测 |
依赖分层技巧
依赖分层技巧
WORKDIR /app
COPY package.json package-lock.json ./ # 只先复制依赖清单
RUN npm ci --omit=dev # 依赖未变则这层命中缓存
COPY . . # 最后复制源码,改动只影响这里
RUN npm run build
CMD ["node","dist/main.js"]典型使用场景
- 多阶段构建:从构建阶段复制编译好的二进制,镜像里不留编译器
- 依赖与源码分层复制,缩短 CI 每次构建的时间
- 复制配置与静态资源,配合 --chown 直接定好属主
- 从上一阶段取前端构建产物,交给精简的运行时镜像
.dockerignore 裁剪的是构建上下文,被忽略的文件 COPY 不到,会直接报文件不存在;改过排除规则后构建失败,先查这一条。
COPY 的来源只能是构建上下文或其它构建阶段;要从网络取文件,请在 RUN 里用下载工具,这样也便于校验与缓存控制。
复制整个目录时容易把本地私钥、日志与依赖目录一起塞进镜像层,即使后续层删除,历史层里依然可以还原出这些文件。