『现学现忘』Docker基础 — 38、COPY指令和ADD指令
COPY 和 ADD 都是 Dockerfile 中的指令,有着类似的作用。它们允许我们将文件从特定位置复制到 Docker 镜像中。
1、COPY指令
(1)COPY指令说明
COPY 指令从 <src> 复制新的文件或目录,并将它们添加到 Docker 容器文件系统的 <dest> 的路径下。
(2)COPY指令格式
COPY 有两种格式:(和 RUN 指令一样)
COPY [--chown=<user>:<group>] <src>... <dest>COPY [--chown=<user>:<group>] ["<src>",... "<dest>"](包含空格的路径使用这种格式)
翻译一下:
COPY [--chown=<user>:<group>] <源路径>... <目标路径>COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]
(3)COPY指令使用
COPY 指令将从构建上下文目录中 <源路径> 的文件或目录,复制到新的一层的镜像内的 <目标路径> 位置。
比如:
COPY package.json /usr/src/app/
<源路径>:可以是多个,甚至可以是通配符,其通配符规则要满足 Go 的filepath.Match规则,
如下:COPY hom* /mydir/
COPY hom?.txt /mydir/
<目标路径>:可以是容器内的绝对路径,也可以是相对于工作目录的相对路径(工作目录可以用WORKDIR指令来指定)。
目标路径不需要事先创建,如果目录不存在,会在复制文件前先行创建缺失目录。
此外,还需要注意一点,使用 COPY 指令,源文件的各种元数据都会保留。比如读、写、执行权限、文件变更时间等。这个特性对于镜像定制很有用,特别是构建相关文件都在使用 Git 进行管理的时候。
(4)其他
在使用该指令的时候还可以加上 --chown=<user>:<group> 选项,来改变文件的所属用户及所属组。
COPY --chown=55:mygroup files* /mydir/
COPY --chown=bin files* /mydir/
COPY --chown=1 files* /mydir/
COPY --chown=10:11 files* /mydir/
2、ADD指令
ADD 指令和 COPY 指令的格式和性质基本一致,但是在 COPY 基础上增加了一些功能。
(1)ADD指令说明
ADD指令有一些额外的功能 :
ADD指令可以让你使用 URL 作为<src>参数。当遇到 URL 时候,可以通过 URL 下载文件并且复制到<dest>(容器中目标路径)。ADD的另一个特性是自动解压文件的能力。如果<src>参数是一个可识别压缩格式(tar,gzip,bzip2…)的本地文件(注:无法实现同时下载并解压),就会被解压到指定容器文件系统的路径<dest>下。
即:ADD指令是将本地文件复制到容器中,也支持通过 URL 进行复制,但效率通常很低(不推荐使用)。
(2)ADD指令格式
ADD 有两种格式:
ADD [--chown=<user>:<group>] <src>... <dest>ADD [--chown=<user>:<group>] ["<src>",... "<dest>"](包含空格的路径使用这种格式)
(3)ADD指令使用
ADD 的最佳用途是将本地压缩包文件自动提取到镜像中:
如下情况,自动解压缩的功能非常有用,比如官方镜像 ubuntu 中:
FROM scratch
ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz /
...
提示:但在某些情况下,如果我们真的是希望复制个压缩文件进去,而不解压缩,这时就不可以使用
ADD命令了。
(4)不推荐使用ADD指令下载文件的原因
由于镜像的体积很重要,所以强烈建议不要使用 ADD 从远程 URL 获取文件,下载文件我们应该使用 curl 或 wget 来代替。
因为如果下载的是个压缩包,需要解压缩,还需要额外的一层 RUN 指令进行解压缩。所以不如直接使用 RUN 指令,然后使用 wget 或者 curl 工具下载,处理权限、解压缩、然后清理无用文件更合理。
因此,这个功能其实并不实用,而且不推荐使用。
示例:
我们应该避免以下操作:(Dockerfile文件)
ADD http://example.com/big.tar.xz /usr/src/things/
RUN tar -xJf /usr/src/things/big.tar.xz -C /usr/src/things \ # 解压
&& make -C /usr/src/things all \ # 编译
&& rm -f /usr/src/things/big.tar.xz # 删除
这个压缩包解压后,rm 命令处于独立的镜像层。
我们可以这样做:
RUN mkdir -p /usr/src/things \
&& curl -SL http://example.com/big.tar.xz \
| tar -xJC /usr/src/things \
&& make -C /usr/src/things all
curl 会下载这个压缩包并通过管道传给 tar 命令进行解压,这样也就不会在文件系统中留下这个压缩文件了。
对于不需要自动解压的文件或目录,应该始终使用 COPY。
最后,认准一个原则:总是使用 COPY(除非我们明确需要 ADD)。
(5)其他
在使用该指令的时候还可以加上 --chown=<user>:<group> 选项来改变文件的所属用户及所属组。
ADD --chown=55:mygroup files* /mydir/
ADD --chown=bin files* /mydir/
ADD --chown=1 files* /mydir/
ADD --chown=10:11 files* /mydir/
3、总结:
在 Docker 官方的 Dockerfile 最佳实践文档中要求,尽可能的使用 COPY,因为 COPY 的语义很明确,就是复制文件而已,而 ADD则包含了更复杂的功能,其行为也不一定很清晰。最适合使用 ADD 的场合,就是所提及的需要自动解压缩的场景。
另外需要注意的是,ADD 指令会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。
因此在 COPY 和 ADD 指令中选择的时候,可以遵循这样的原则,所有的文件复制均使用 COPY 指令,仅在需要自动解压缩的场景使用 ADD指令。
参考:
『现学现忘』Docker基础 — 38、COPY指令和ADD指令的更多相关文章
- 『现学现忘』Docker基础 — 16、Docker中的基本概念和底层原理
目录 1.Docker的底层原理 2.Docker中常用的基本概念 3.run命令的运行流程 4.为什么Docker比VM快 Docker架构图: 我们依照Docker架构图进行Docker基础概念的 ...
- 『现学现忘』Docker基础 — 34、DockerFile文件详解
目录 1.DockerFile文件说明 2.Dockerfile构建过程解析 (1)Docker容器构建三步骤 (2)Dockerfile文件的基本结构 (3)Dockerfile注意事项 (4)Do ...
- 『现学现忘』Docker基础 — 36、CMD指令和ENTRYPOINT指令的区别
目录 1.CMD指令和ENTRYPOINT指令说明 2.CMD指令只有最后一条生效的原因 3.CMD指令演示 4.ENTRYPOINT指令演示 5.总结 CMD指令和ENTRYPOINT指令作用都是指 ...
- 『现学现忘』Docker基础 — 9、Docker简介
目录 1.什么是Docker? 2.Docker的出现解决了什么问题? 3.Docker的特别之处 4.Docker相关网站 1.什么是Docker? 2010年dotCloud公司在旧金山成立,PA ...
- 『现学现忘』Docker基础 — 25、Docker镜像讲解
目录 1.镜像是什么 2.Docker镜像获取的方式 3.Docker镜像加载原理 (1)UnionFS(联合文件系统) (2)Docker镜像加载原理 1.镜像是什么 镜像是一种轻量级.可执行的独立 ...
- 『现学现忘』Docker基础 — 26、Docker镜像分层的理解
目录 1.分层的镜像 2.加深理解 3.特别说明 1.分层的镜像 我们可以去下载一个镜像,注意观察下载的日志输出,可以看到Docker的镜像是一层一层的在下载. 思考:为什么Docker镜像要采用这种 ...
- 『现学现忘』Docker基础 — 27、Docker镜像的commit操作
目录 1.commit命令作用 2.commit命令说明 3.示例演示 1.commit命令作用 在运行的容器中,并在镜像的基础上做了一些修改,我们希望保存起来,封装成一个新的镜像,方便我们以后使用, ...
- 『现学现忘』Docker基础 — 28、Docker容器数据卷介绍
目录 1.什么是Docker容器数据卷 2.数据卷的作用 3.数据卷的使用 1.什么是Docker容器数据卷 Docker容器数据卷,即Docker Volume(卷). 当Docker容器运行的时候 ...
- 『现学现忘』Docker基础 — 32、通过DockerFile的方式挂载数据卷
目录 1.简单了解一下DockerFile 2.通过DockerFile的方式挂载数据卷 (1)创建DockerFile文件 (2)编辑Dockerfile文件 (3)构建Dokcer镜像 (4)启动 ...
随机推荐
- 帝国CMS只备份栏目和模板的方法
方法一:不备份所有帝国cms数据内容表 我们知道帝国cms有8大模型,分别是 1.新闻系统数据表 ( phome_ecms_news )2.下载系统数据表 ( phome_ecms_download ...
- C++五子棋(一)——开发环境
开发环境 环境准备 Visual Studio Windows EasyX图形库 素材文件 素材文件已经准备了,点击此处获取 百度网盘链接 提取码:su6p 创建项目 打开Visual Studio ...
- Python Windows 快捷键自动给剪贴板(复制)图片添加水印
编写一个能在windows上使用的按下快捷键自动给剪贴板(复制)的图片添加水印的小工具.plyer.PIL.pyinstaller.pynput.win32clipboard库.记录自己踩过的坑,部分 ...
- 搜索与图论①-深度优先搜索(DFS)
深度优先搜索(DFS) 例题一(指数型枚举) 把 1∼n 这 n 个整数排成一行后随机打乱顺序,输出所有可能的次序. 输入格式 一个整数 n. 输出格式 按照从小到大的顺序输出所有方案,每行 1 个. ...
- Java基础语法Day_04
第11节 开发工具-IDEA day04_01_集成开发环境IDE的概述 day04_02_IntelliJ-IDEA的安装 day04_03_IDEA的项目结构 day04_04_IDEA的Hell ...
- XCTF练习题---WEB---xff_referer
XCTF练习题---WEB---xff_referer flag:cyberpeace{9626408a4b37eab65854d8ccd22f671c} 解题步骤: 1.观察题目,打开场景 2.注意 ...
- Spring (IOC)配置
就是这个东西,里面的不同标签,所代表的不同含义 beans 里面有很多的bean ,每一个bean都是容器里面的一个对象 1.别名alias (另外的一个名字) XML <alias na ...
- [AcWing 797] 差分
点击查看代码 #include<iostream> using namespace std; const int N = 1e5 + 10; int a[N], b[N]; void in ...
- 数据交换格式 JSON
1. 什么是 JSON 概念 : JSON 的英文全称是 JavaScript ObjEct Notation, 即 "JavaScript 对象表示法" . 简单来讲 : JSO ...
- 1.16 Linux该如何学习(新手入门必看)
本节旨在介绍对于初学者如何学习 Linux 的建议.如果你已经确定对 Linux 产生了兴趣,那么接下来我们介绍一下学习 Linux 的方法. 如何去学习 学习大多类似庖丁解牛,对事物的认识一般都是由 ...