使用dockerfile创建镜像时,肯定会涉及到文件复制、文件下载等操作,这时需要ADD指令来完成。

  ADD 语法

ADD [--chown=<user>:<group>] <src>... <dest>
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]

  ADD 语义

  · 第二种形式需要路径包含空格。

  · --chown仅支持dockerfile构建Linux容器,Windows容器并不适用。由于LinuxWindows中的用户和用户组不同,因此使用/etc/passwd/etc/group将用户和组名称转换为ID时限制了此功能仅适用于基于Linux操作系统的容器。

  · ADD指令从复制文件、目录以及远程文件到镜像文件系统的。

  · 可以指定多个资源,但如果它们是文件或目录,则它们的路径被解释为相对于构建上下文的源。

  · 每个可以包含通配符,匹配将使用Go语言的filepath.Match规则进行。例如:

  1) *配合任意多个任意字符,匹配hom开头的任意文件。

ADD hom* /mydir/

  2) ?用于匹配单个字符,匹配home.txthoms.txt等等文件。

ADD hom?.txt /mydir/

  · 是一个绝对路径或者相对于WORKDIR的路径,将被复制到目标容器中。例如:

  1) 的值是:/relativeDir/

COPY test.txt relativeDir/

  2) 的值是:绝对路径/absoluteDir/

COPY test.txt /absoluteDir/

  · 除非可选的--chown标志指定给定的用户名、组名或UID/GID组合来请求复制内容的特定所有权,否则所有新文件和目录都将使用UIDGID为0创建。--chown标志的格式允许usernamegroupname字符串,也可以是任意组合的整数UIDGID。提供没有groupname的用户名或没有GIDUID将使用与GID相同的数字UID。如果提供了用户名或组名,容器root文件系统的/etc/passwd/etc/group文件将分别用于执行从名称到整数UIDGID的转换。

ADD --chown=55:mygroup files* /somedir/
ADD --chown=bin files* /somedir/
ADD --chown=1 files* /somedir/
ADD --chown=10:11 files* /somedir/

  · 如果容器root文件系统不包含/etc/passwd/etc/group文件,并且--chown标志中使用了用户名或组名,则~操作将失败。使用数字标识不需要查找,也不依赖于容器根文件系统内容。

  · ADD遵循以下规则:

  1) 路径必须在构建的上下文中;不能复制../something/something,因为docker构建的第一步是将上下文目录(和子目录)发送到docker守护进程。

  2) 如果是一个URL且不是以反斜杠结尾,那么将从URL下载文件并复制到。

  3) 如果是一个URL且不是以反斜杠结尾,那么文件名从URL推断,下载的文件是/。例如:ADD http://example.com/foobar/将创建文件/foobar,URL必须包含非路径以便可以推断出文件名。

  4) 如果是一个目录,复制目录的整个内容,包括文件系统元数据。目录本身不被复制,只复制其内容。

  5) 如果是使用可识别的压缩格式(identity、gzip、bzip2或xz)的本地tar归档文件,则将其解压为一个目录。来自远程URL的资源不会解压缩。当目录被复制或解包时,它的行为与tar -x相同,结果是:

   ① 目的地路径上存在的任何东西。

   ② 源目录树的内容,以“2”为单位解决冲突。

   ③ 文件是否被标识为可识别的压缩格式完全取决于文件的内容,而不是文件的名称。例如,如果一个空文件碰巧以结尾.tar.gz这将不会被识别为压缩文件,也不会生成任何类型的解压缩错误消息,而是将文件简单地复制到目标。

  6) 如果是任何其他类型的文件,则单独复制它及其元数据。在这种情况下,如果以一个斜杠/结尾,它将被视为一个目录,的内容将写入/base()。

  7) 如果直接或由于使用通配符指定了多个资源,则必须是一个目录,并且必须以斜杠/结尾。

  8) 如果没有以尾随斜杠结尾,它将被视为常规文件,的内容将写入。

  9) 如果不存在,则会连同路径中所有丢失的目录一起创建。

  ADD 示例

  · 指定为带通配符文件,指定绝对目录。

  1) 进入/securitit/dockerfile/add目录(根据个人选择,这是本文使用的目录),新增demo.png和Test.png,用于dockferfile

Dockerfile add dockerfile ADD目录的权限_Docker

  2) 进入/securitit/dockerfile/目录,创建dockerfile文件。

FROM nginx
MAINTAINER Securitit
ADD /add/*.png /securitit/
CMD /bin/bash

  3) 执行如下的构建命令,基于dockerfile构建镜像。

docker build -f /securitit/dockerfile/dockerfile -t securitit-nginx-add:1.0.0.1 .

Dockerfile add dockerfile ADD目录的权限_ADD_02

  4) 查看镜像信息。

docker images

Dockerfile add dockerfile ADD目录的权限_ADD_03

  5) 指定通过dockerfile生成的镜像启动容器。

docker run --name securitit-nginx-add -it -d -p 80:80 securitit-nginx-add:1.0.0.1

Dockerfile add dockerfile ADD目录的权限_Docker_04

  6) 查看容器信息。

docker ps -a

Dockerfile add dockerfile ADD目录的权限_COPY_05

  7) 进入容器,确认文件是否已添加到容器内/securitit/目录下。

Dockerfile add dockerfile ADD目录的权限_Dockerfile add_06

  从结果可见,demo.pngTest.png已从宿主机的/securitit/dockerfile/add/目录下复制到了容器/securitit/目录下。

  总结

  dockerfile指令中,ADDCOPY非常相似,实现的功能也十分接近。ADD相比COPY,做了功能增强,可以’完成压缩文件解压并添加到镜像中’和’从URL下载文件到镜像中’。太细节的内容,可以查看系列博文关于ADDCOPY的命令解析。

  若文中存在错误和不足,欢迎指正!