『现学现忘』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文章数据添加太多到某一张分表中了,如图 这是极其不合理的,需要优化下,所以这篇文章要告诉大家的也就是如何互相转移分表之间的数据. 我现在要将:phome_ecms_news_data ...
- 前台js发请求参数与后台接参数的问题
js函数中写参数,ajax中写参数,示例如下: function informationQuery(sign){//预警详情条件查询 $.get("/detail/informationQu ...
- C. Sum of Cubes
原题链接 https://codeforces.com/problemset/problem/1490/C 题目 题意 如果一个数 n = x3 + y3 (x, y可以相等, 且> 0) 输出 ...
- 多行,溢出隐藏 css
.ellipsis-line{width:200px; line-height:18px;font-size:14px; overflow:hidden; text-overflow:ellipsi ...
- python黑帽子(第四章)
Scapy窃取ftp登录账号密码 sniff函数的参数 filter 过滤规则,默认是嗅探所有数据包,具体过滤规则与wireshark相同. iface 参数设置嗅探器索要嗅探的网卡,默认对所有的网卡 ...
- 【第三课】常用的Linux命令(学习笔记)
4月8日 学习笔记打卡
- Java基础语法Day_06(面相对象和封装)
第1节 描述类介绍与使用 day06_01_面向对象思想的概述 day06_02_面向对象思想的举例 day06_03_类和对象的关系 day06_04_类的定义 day06_05_对象的创建及其使用 ...
- ValidForm5.3.2 忽略表单项校验详解
ValidForm 官方文档 项目的需求是这样的:一个checkbox,一个input,选中checkbox的时候,需要校验input,取消选中的时候,不要校验input. <input typ ...
- c# 一些警告的处理方法
在使用.Net 6开发程序时,发现多了很多新的警告类型.这里总结一下处理方法. CS8618 在退出构造函数时,不可为 null 的 属性"Name"必须包含非 null 值 经常 ...
- 1.16 Linux该如何学习(新手入门必看)
本节旨在介绍对于初学者如何学习 Linux 的建议.如果你已经确定对 Linux 产生了兴趣,那么接下来我们介绍一下学习 Linux 的方法. 如何去学习 学习大多类似庖丁解牛,对事物的认识一般都是由 ...