『现学现忘』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)启动 ...
随机推荐
- JavaScript学习总结6-apply
JS中的apply方法可以控制this指向 任何JS支持的类型都可以转化为JSON JS对象是键值对型的,JSON是字符串型的 原型对象:__proto__ JS万物皆对象,ES6开始提供了对后端开发 ...
- Java语言学习day08--7月7日
###13遍历数组 * A:遍历数组 * 在操作数组时,经常需要依次访问数组中的每个元素,这种操作称作数组的遍历 * B:练习 public class ArrayDemo04 { publ ...
- Java语言学习day20--7月26日
###11抽象类的产生 A:抽象类的产生 a:分析事物时,发现了共性内容,就出现向上抽取.会有这样一种特殊情况,就是方法功能声明相同,但方法功能主体不同.那么这时也可以抽取,但只抽取方法声明,不抽取方 ...
- 论文解读(GCC)《Graph Contrastive Clustering》
论文信息 论文标题:Graph Contrastive Clustering论文作者:Huasong Zhong, Jianlong Wu, Chong Chen, Jianqiang Huang, ...
- 类变量_main方法_代码块
需要解决的问题: 统计一共创建了多少个对象 类变量(静态变量) 被所有对象共享 可以通过 类名(推荐)|对象名.变量名 方式来访问 main main 方法 是虚拟机在调用 args 传值灵活 结果 ...
- AcWing-3167. 星星还是树 -c++题解(模拟退火)
在二维平面上有 n 个点,第 i 个点的坐标为 (xi,yi).请你找出一个点,使得该点到这 n个点的距离之和最小.该点可以选择在平面中的任意位置,甚至与这 n个点的位置重合. 输入格式 第一行包 ...
- 用 Docker 快速搭建 Kafka 集群
开源Linux 一个执着于技术的公众号 版本 •JDK 14•Zookeeper•Kafka 安装 Zookeeper 和 Kafka Kafka 依赖 Zookeeper,所以我们需要在安装 Kaf ...
- ShardingSphere 集成 CosId 实战
背景 在软件系统演进过程中,随着业务规模的增长 (TPS/存储容量),我们需要通过集群化部署来分摊计算.存储压力. 应用服务的无状态设计使其具备了伸缩性.在使用 Kubernetes 部署时我们只需要 ...
- Spring 源码(8)Spring BeanPostProcessor的注册、国际化及事件发布机制
上一篇文章https://www.cnblogs.com/redwinter/p/16198942.html介绍了Spring的注解的解析过程以及Spring Boot自动装配的原理,大概回顾下:Sp ...
- app嵌套页
Wdatepicker