当前位置: 首页 > news >正文

【docker】Dockerfile中COPY和ADD的区别理解,多阶段构建中COPY的用法

在 Dockerfile 中,COPYADD 都是用来将文件从主机复制到 Docker 镜像中的指令。它们有些相似,但在功能上有一些关键的区别。

单阶段构建

1. 基本区别

  • COPY:简单地将文件或目录从主机系统复制到容器的指定路径,不做任何额外的处理。

  • ADD:除了执行与 COPY 相同的操作外,还能处理一些额外的功能:

    • 支持从 URL 下载文件并复制到容器中。
    • 支持自动解压 .tar 格式的压缩包(如 .tar.gz.tar.bz2 等)。

2. 理解与逻辑

  • COPY 用于最基础的文件拷贝操作,语法简单,行为明确,通常在我们不需要额外处理(如解压文件或从远程服务器下载文件)的情况下使用。

  • ADD 提供了更多的功能(如下载和解压),但由于其具有自动处理压缩文件的功能,有时会增加不必要的复杂性。比如,如果我们不需要解压 .tar 文件,使用 ADD 可能会带来一些不期望的行为。因此,推荐使用 COPY,只有在需要解压文件或从网络下载时,才使用 ADD

3. 使用场景对比

特性COPYADD
基本功能将文件从主机复制到镜像中将文件从主机复制到镜像中
支持解压不支持解压文件支持自动解压 .tar 文件
支持 URL只支持本地路径支持从 URL 下载文件并复制
推荐使用场景仅复制文件或目录,没有额外需求需要解压 .tar 文件或从 URL 下载文件
语法COPY <src> <dest>ADD <src> <dest>

4. 举例说明

示例 1:使用 COPY 复制文件
COPY ./myfile.txt /app/myfile.txt

这将把主机上的 myfile.txt 文件复制到容器中的 /app/ 目录。

示例 2:使用 ADD 复制文件并解压
ADD ./myarchive.tar.gz /app/

这将把 myarchive.tar.gz 文件复制到 /app/ 目录,并自动解压它。假如 myarchive.tar.gz 中包含多个文件,ADD 会自动将这些文件解压到 /app/ 目录中。

示例 3:使用 ADD 从 URL 下载文件
ADD http://example.com/file.tar.gz /app/

这将从 http://example.com/file.tar.gz 下载文件,并将其复制到 /app/ 目录中,同时也会解压文件。

总结:

  • COPY 是最基础的文件复制操作,语义明确,推荐用于文件复制。
  • ADD 除了复制文件外,支持自动解压和从 URL 下载,但增加了不必要的复杂性,除非有解压或下载需求,否则优先使用 COPY

多阶段构建

多阶段构建(multi-stage builds) 中,COPY 可以从一个阶段复制文件到另一个阶段。

如何使用 COPY 在不同阶段之间传递文件

在多阶段构建中,COPY 可以通过指定源镜像的名称来从一个构建阶段复制文件到另一个阶段。

语法

COPY --from=<stage_name_or_index> <src_path> <dest_path>
  • --from=<stage_name_or_index>:指定从哪个构建阶段复制文件。如果是第一个阶段,可以使用 0,如果是多个阶段中的其他阶段,可以使用阶段的名称或索引。
  • <src_path>:源路径,表示要复制的文件或目录。
  • <dest_path>:目标路径,表示复制到容器中的位置。

示例:多阶段构建中的 COPY 使用

假设你有一个 Node.js 项目,首先需要编译和构建文件,然后在最终的镜像中仅包含构建后的产物(比如构建出来的静态文件或编译后的代码)。

# 第一阶段:构建阶段
FROM node:16 AS builder
WORKDIR /app
COPY . .
RUN npm install && npm run build

# 第二阶段:最终镜像
FROM nginx:alpine 
# 从构建阶段复制编译好的静态文件到 Nginx 服务器的默认目录

COPY --from=builder /app/build /usr/share/nginx/html 

# 暴露端口

EXPOSE 80 

解释

  • 在第一阶段,我们使用 node:16 镜像构建项目,执行 npm installnpm run build

  • 在第二阶段,我们使用 nginx:alpine 镜像来部署构建后的静态文件。通过 COPY --from=builder /app/build /usr/share/nginx/html,我们从名为 builder 的第一阶段中复制 /app/build 目录到 Nginx 的默认静态文件目录 /usr/share/nginx/html

为什么使用多阶段构建?

  • 减小镜像大小:你可以只将构建过程中需要的文件复制到最终镜像中,避免将临时的构建工具和中间文件包含在内,从而减小最终镜像的体积。

  • 清晰的分层管理:将不同的构建步骤分开,可以更清晰地管理每个构建步骤的依赖。

dockerfile演示

FROM quay.io/0voice/node:18.16.0 as stage0
RUN npm config set registry https://mirrors.huaweicloud.com/repository/npm/
COPY ./user-web /src/user-web
WORKDIR /src/user-web
RUN npm install
RUN npm run build

FROM quay.io/0voice/golang:1.20 as stage1
RUN go env -w GOPROXY=https://goproxy.cn,https://proxy.golang.com.cn,direct
ADD ./user /src/user
WORKDIR /src/user
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o user .

FROM quay.io/0voice/alpine:3.18 as stage2
ADD ./curl-amd64 /usr/bin/curl
RUN chmod +x /usr/bin/curl
WORKDIR /app
ADD ./user/dev.config.yaml /app/config.yaml
COPY --from=stage0 /src/user-web/dist /app/www
COPY --from=stage1 /src/user/user /app
ENTRYPOINT ["./user"]
CMD ["--config=config.yaml"]


https://github.com/0voice

http://www.dtcms.com/a/98717.html

相关文章:

  • 开发环境部署
  • 应用待机分组管控是啥
  • 智能预测维护:让设备“未卜先知”,减少宕机烦恼
  • 程序化广告行业(40/89):手游归因与投放异常解析
  • libva基础
  • SAP学习笔记 - 用Deepseek 整理SAP 07 - MRP要素的缩略语一览
  • ADC笔记
  • Windows下安装和配置Redis
  • 前台线程和后台线程
  • 算法刷题记录——题解目录汇总(持续更新)
  • Docker学习之dockerfile篇(day8)
  • 算法刷题记录——LeetCode篇(9.1) [第801~810题]
  • 精准的集装箱号码识别技术在过磅系统中的应用,显著提升物流效率、减少人为错误
  • 基于kafka的分布式日志收集平台项目(第三部分)
  • 页码设置相关问题记录
  • React 揭秘:从新手到高手的进阶之路
  • day19学习numpy库和matplotlib库
  • 使用postcss-px-to-viewport-8-plugin将页面转响应式
  • git | 版本切换的相关指令
  • Qt Creator 中文 “error: C2001: 常量中有换行符“ 问题解决方法
  • 树的基础_遍历(蓝桥云课)
  • Qt之Service开发
  • 复盘与导出工具最新版V20.0版本更新--覆盖标记新增龙头标记---连板标记--普通标记3种选择
  • 深度学习4.4笔记
  • 游戏AI实现-GOAP
  • 【华为OD技术面试真题 - 技术面】- Java面试题(16)
  • 【免费】中国电子学会2025年03月份青少年软件编程Python等级考试试卷六级真题(含答案)
  • 解决obsidian无法加载社区的解决的尝试
  • DeepSeek-R1国产大模型实战:从私有化部署到内网穿透远程使用全攻略
  • 【Java】Java核心知识点与相应面试技巧(七)——类与对象(二)