使用dockerfile
创建镜像时,肯定会涉及到文件复制、文件下载等操作,这时需要COPY
指令来完成。
COPY 语法
COPY [--chown=<user>:<group>] <src>... <dest>
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]
COPY 语义
· 第二种形式要求路径包括空格。
· --chown
仅支持dockerfile
构建Linux
容器,Windows
容器并不适用。由于Linux
和Windows
中的用户和用户组不同,因此使用/etc/passwd
和/etc/group
将用户和组名称转换为ID时限制了此功能仅适用于基于Linux操作系统的容器。
· COPY
指令从复制文件、目录到镜像文件系统的。
· 可以指定多个资源,但如果它们是文件或目录,则它们的路径被解释为相对于构建上下文的源。
· 每个可以包含通配符,匹配将使用Go
语言的filepath.Match
规则进行。例如:
1) *配合任意多个任意字符,匹配hom
开头的任意文件。
ADD hom* /mydir/
2) ?用于匹配单个字符,匹配home.txt
、homs.txt
等等文件。
ADD hom?.txt /mydir/
· 是一个绝对路径或者相对于WORKDIR
的路径,将被复制到目标容器中。例如:
1) 的值是:/relativeDir/
。
COPY test.txt relativeDir/
2) 的值是:绝对路径/absoluteDir/
。
COPY test.txt /absoluteDir/
· 当复制文件或目录包含特殊字符(例如:[
、]
),需要进行转义。
1) 如果为arr[0].txt
,则需进入如下转义:
COPY arr[[]0].txt /mydir/
· 除非可选的--chown
标志指定给定的用户名、组名或UID
/GID
组合来请求复制内容的特定所有权,否则所有新文件和目录都将使用UID
和GID
为0创建。--chown
标志的格式允许username
和groupname
字符串,也可以是任意组合的整数UID
和GID
。提供没有groupname
的用户名或没有GID
的UID
将使用与GID
相同的数字UID
。如果提供了用户名或组名,容器root
文件系统的/etc/passwd
和/etc/group
文件将分别用于执行从名称到整数UID
或GID
的转换。
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
标志中使用了用户名或组名,则~操作将失败。使用数字标识不需要查找,也不依赖于容器根文件系统内容。
· COPY
遵循以下规则:
1) 路径必须在构建的上下文中;不能复制../something/something
,因为docker
构建的第一步是将上下文目录(和子目录)发送到docker
守护进程。
2) 如果是一个目录,复制目录的整个内容,包括文件系统元数据。目录本身不被复制,只复制其内容。
3) 如果是任何其他类型的文件,则单独复制它及其元数据。在这种情况下,如果以一个斜杠/
结尾,它将被视为一个目录,的内容将写入/base
()。
4) 如果直接或由于使用通配符指定了多个资源,则必须是一个目录,并且必须以斜杠/
结尾。
5) 如果没有以尾随斜杠结尾,它将被视为常规文件,的内容将写入。
6) 如果不存在,则会连同路径中所有丢失的目录一起创建。
COPY 示例
· 指定为带通配符文件,指定绝对目录。
1) 进入/securitit/dockerfile/copy
目录(根据个人选择,这是本文使用的目录),新增redis.conf
、nginx.conf
和keepalived.conf
,用于dockferfile
。
2) 进入/securitit/dockerfile/
目录,创建dockerfile
文件。
FROM nginx
MAINTAINER Securitit
COPY /copy/*.conf /securitit/
CMD /bin/bash
3) 执行如下的构建命令,基于dockerfile
构建镜像。
docker build -f /securitit/dockerfile/dockerfile -t securitit-nginx-copy:1.0.0.1 .
4) 查看镜像信息。
docker images
5) 指定通过dockerfile
生成的镜像启动容器。
docker run --name securitit-nginx-copy -it -d -p 80:80 securitit-nginx-copy:1.0.0.1
6) 查看容器信息。
docker ps -a
7) 进入容器,确认文件是否已添加到容器内/securitit/
目录下。
从结果可见,redis.conf
、nginx.conf
和keepalived.conf
已从宿主机的/securitit/dockerfile/copy/
目录下复制到了容器/securitit/
目录下。
总结
dockerfile
指令中,COPY
和ADD
非常相似,实现的功能也十分接近。ADD
相比COPY
,做了功能增强,可以’完成压缩文件解压并添加到镜像中’和’从URL下载文件到镜像中’。COPY
是精简版的ADD
指令,如果可以熟练的使用ADD
指令,那么COPY
指令其实已无太大用处。
若文中存在错误和不足,欢迎指正!