ADD
ADD 有两种形式:
ADD [--chown=<user>:<group>] <src>... <dest>
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]
(地址包含空格的情况是需要用到这种形式)
注意:
--chown
特性只有在Dockerfile被用来构建Linux的容器时被支持,不会在Windows容器上使用。由于user 和 group 所有权概念在Linux和windows之间不可以转换,因此用来转换user和group names 到 IDs/etc/passwd
和/etc/group
的使用限制这个特性只能在基于Linux的操作系统容量上使用。
ADD
指令从<src>
上复制新的文件,目录或者是远程文件的URLs和添加他们到<dest>
指定的镜像里的文件系统。
可以指定多个<src>
资源,但如果它们是文件或者是目录,它们会被解析成相对于构建上下文资源的路径。
每一个<src>
可以包含通配符和根据Go’s fiepath.Match 规则完成匹配。例如:
ADD hom* /mydir/ # adds all files starting with "hom"
ADD hom?.txt /mydir/ # ? is replaced with any single character, e.g., "home.txt"
<dest>
可以是一个绝对路径,或者是相对 WORKDIR
的路径,源文件会被复制到目标容器中。
ADD test relativeDir/ # adds "test" to `WORKDIR`/relativeDir/
ADD test /absoluteDir/ # adds "test" to /absoluteDir/
当添加文件和目录包含了特殊字符(例如 [
和]
),你需要去根据Golang规则去转义那些路径去防止它们被当作一个统配符。例如,
所有新文件和目录被创建为UID和GID为0,除非使用可选的标签 --chown
指定一个给予的username和groupname,或者用UID/GID的的组合去指定添加的内容的所有权。--chown
flag的格式既允许username和groupname 的string组合也允许之间integer UID和GID组合。提供username而不提供groupname或者提供UID而不提供GID,这种情况将会使用相同的数字UID作为GID。如果username或groupname被提供,容器的根文件系统/etc/passwd
和/etc/group
文件将会分别用来执行从name到integer UID或GID的转化。下面的例子展示了--chown
标签合法的定义:
ADD --chown=55:mygroup files* /somedir/
ADD --chown=bin files* /somedir/
ADD --chown=1 files* /somedir/
ADD --chown=10:11 files* /somedir/
如果容器根文件系统不包含 /etc/passwd
或不包含 /etc/group
文件和user 或group名字用在 --chown
标签,构建将会在ADD
操作上失败。使用数字ID不需要查找,并且不依赖于容器根文件系统内容。
当<src>
是远程文件路径URL的时候, 目标文件将会拥有600的权限。如果远程文件被接收时拥有HTTP Last-Modified
header,header上的timestamp将会被用来设置在目标文件的mtime
。然而, 像一些其它文件在ADD
的处理中,mtime
将不会被包含在文件是否改动和缓存是否被更新的决定因素。
注意:如果你通过将Dockerfile通过STDIN来构建(
docker build - < somefile
), 这是没有构建内容的,所以Dockerfile
只能包含基于ADD
指令包含URL。你可以通过STDIN来传送一个压缩的文档:(docker build - < archive.tar.gz
),Dockerfile
在文档的根目录剩下的都会用来作为构建的内容。
注意:如果你的URL有身份验证保护,你需要使用
RUN wget
,RUN curl
或者 使用其它工具在容器里面因为ADD
指令不知道身份验证。
注意: 如果
<src>
的内容发生改变,第一个遇到的ADD
指令将会使后面Dockerfile所有的指令的缓存失效。这里还包括RUN
指令的缓存也会失效。请查看Dockerfile
最佳实践指南来获取更多信息。
ADD
遵从的其它规则:
<src>
的路劲一定要是构建上下文里面;你不能ADD ../something /something
, 因为docker build
的第一步是发送上下文目录(和子目录)到docker daemon。- 如果
<src>
是一个URL<dest>
没有以斜杠结尾,那么文件会从URL中被下载和复制到<dest>
。 - 如果
<src>
是一个URL<dest>
以斜杠结尾,那么可以从URL推断出文件名以及文件被下载到<dest>/<filename>
。例如,ADD http://example.com/foobar /
会创建/foobar
文件。URL必须有一个特定的路径为了可以使合适的文件名被发现(http://example.com
这种路径没有效)。 - 如果
<src>
是一个路径,那么整个目录里的内容都会被复制,包括系统文件元数据。
注意:目录本身自己是不会被复制的,只是它里面的内容。
- 如果
<src>
是一个公认的压缩包格式的本地archive文件(identidy, gzip,bzip2 或者 xz)那么它会被解压成一个目录。远程URLs的资源实不会被解压的。当这个目录被复制或者解压,它跟tar -x
行为一样。
文件是否是被认定为一个压缩文件形式取决于文件内容,而不是文件的名字。例如,有一个空文件恰巧以
.tar.gz
结尾,这种是不会被认定为压缩文件已经将不会生成任何形式的解压错误的信息,然而这个文件会被简单地复制取目标地址。
- 如果
<src>
是一些其它类型的文件,它会跟它的元数据被单独地复制。在这种情况,如果<dest>
以斜杠结尾,那么它将会被当作一个目录以及<src>
的内容将会被写入<dest>/base(<src>)
。 - 如果多个
<src>
资源被指定,直接地或者使用通配符,<dest>
必须是目录,以及它必须以斜杠结尾/
。 - 如果
<dest>
不是使用斜杠结尾,它会被当作一个普通文件和<src>
的内容将会被写在<dest>
。 - 如果
<dest>
不存在,那么它会跟全部缺失的目录一起被创建。