COPY

COPY有两种形式:

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

包含空白的路径需要后一种形式。

NOTE:

--chown功能仅在用于构建Linux容器的Dockerfiles上受到支持,在Windows容器上不起作用。由于用户组所有权概念无法在LinuxWindows之间进行转换,因此使用/etc/passwd/etc/group用户名组名转换为ID限制了该功能,使得该功能仅适用于基于Linux OS的容器。

COPY指令从拷贝新的文件或目录,将它们添加到容器文件系统的指定路径中去。

每一个可能包含通配符的路径会通过Gofilepath.Match(参考ADD中的解释)规则进行匹配。例如:

添加所有文件名以”hom“开头的文件:

COPY hom* /mydir/

在下面的示例中,?可以被替换为任何单个字符,例如"home.txt"

COPY hom?.txt /mydir/

是绝对路径,或相对于WORKDIR的路径,源文件将被拷贝到目标容器所在文件系统的路径中。

下面的示例使用相对路径,并将"test.txt“添加到 /relativeDir/

COPY test.txt relativeDir/

而此示例使用了绝对路径,并向/absoluteDir/添加了"test.txt"

COPY test.txt /absoluteDir/

在拷贝包含特殊字符的文件或目录(如 [和]) 时,我们需要按照Golang规则对这些路径进行转义,以防止它们被视为匹配模式。例如,要添加名为 arr[0].txt的文件,请使用以下文件:

COPY arr[[]0].txt /mydir/

所有新文件和目录均以值为0UIDGID创建,除非通过可选的--chown指定用户名组名UID/GID组合,来为添加的内容指定所有权(ownership)--chown允许使用用户名和组名字符串的格式,或直接使用整数形式UIDGID。如果使用不带组名用户名或不带GIDUID的形式,则会使用与UID相同的值来作为GID。如果提供了用户名组名,则会根据容器根文件系统中的/etc/passwd/etc/group文件来将用户名组名name的形式转换为整数的形式。以下示例显示了--chown的有效定义:

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

如果容器的根文件系统不包含/etc/passwd/etc/group文件,并且以用户组名的形式使用--chown,那么关于COPY构建的操作将会失败。使用数值ID形式的用户,则不需要查询且不会去依赖容器根文件系统的内容。

NOTE:

在构建镜像时,如果通过标准输入来传递Dockerfile(docker build - < somefile),则不会存在构建上下文,COPY将无法被使用。

COPY接受可选的--from=选项标志,该标志可用于将拷贝的源位置设置为先前的构建阶段(使用FROM .. AS 创建),该阶段将代替用户发送给docker守护进程的构建上下文。如果找不到具有指定名称的构建阶段,则尝试改用具有相同名称的镜像。

示例:

ARG VERSION=7

FROM centos:$VERSION AS centos
RUN mkdir test_dir && cd test_dir && touch file{1,2} && echo hello world > file1

FROM alpine:latest
COPY --from=centos /test_dir/file1 /tmp
CMD ["/bin/echo", "process finished"]
docker run -it camelgem/copy:v1 /bin/sh

liuyang@liuyangdeiMac docker % docker run -it camelgem/copy:v1 /bin/sh               
$ cd /tmp && ls
file1

# 通过上面的Dockerfile,我们将镜像centos中我们新创建的file文件,通过COPY指令的--from=<name>选项标志拷贝到了alpine镜像的文件系统中。通过--from=centos,我们将COPY指令的上下文替换为centos文件系统的目录上下文,而不是我们在命令行指定的构建上下文。

COPY指令遵照以下规则:

  • <src>路径必须包含在构建上下文之中;不能使用COPY ../something /something, 因为docker build的第一步就是将上下文目录(及其子目录)发送给docker守护进程。

  • 如果<src>是一个目录,整个目录的内容包括文件系统的元数据都会被拷贝到目标路径中。

NOTE:

目录本身并不会被拷贝,仅仅只是拷贝目录中的内容。

  • 如果<src>是任意其他类型的文件,它和它的元数据会被单独拷贝。在这种情况下,如果<dest>以斜线结尾,它会被当作目录,<src>的内容会被写入到<dest>/base(<src>)

  • 如果通过直接或使用通配符的方式指定了多个<src>资源,那么<dest>必须是一个目录,并且必须以斜线结尾。

  • 如果<dest>没有以斜线结尾,那么它会被当成一个正常的文件,而<src>的内容会被写入到这个文件中。

  • 如果<dest>不存在,那么会在它的路径下创建所有缺失的目录。

NOTE:

如果<src>中的内容被更改了,在构建镜像时,遇到的第一个COPY指令会使后续指令的缓存失效。这其中还包含了RUN指令的缓存。查看Dockerfile Best Practice guide - Leverage build cache来获取更多信息。

Last updated