1.介绍

1.1 官方描述翻译

docker cp工具将SRC_PATH的内容复制到DEST_PATH。你可以从容器的文件系统复制到本地机器,或者反过来,从本地文件系统复制到容器。如果SRC_PATHDEST_PATH指定为**-**,你还可以从STDIN流式传输tar存档,或者传输到STDOUTCONTAINER可以是正在运行的或已停止的容器。SRC_PATHDEST_PATH可以是文件或目录。``
docker cp命令假定容器路径是相对于容器的/(根)目录。这意味着提供初始的正斜杠是可选的;命令将compassionate_darwin:/tmp/foo/myfile.txtcompassionate_darwin:tmp/foo/myfile.txt视为相同。本地机器路径可以是绝对或相对值。命令将本地机器的相对路径解释为运行docker cp的当前工作目录相对路径。
cp命令的行为类似于Unix的cp -a命令,即可能保留权限的同时递归复制目录。所有权被设置为目标处的用户和主要组。例如,复制到容器的文件以root用户的UID:GID创建。复制到本地机器的文件以调用docker cp命令的用户的UID:GID创建。但是,如果你指定了-a选项,docker cp会将所有权设置为源处的用户和主要组。如果你指定了-L选项,docker cp会跟随SRC_PATH中的任何符号链接。docker cp不会为DEST_PATH创建不存在的父目录。
假设路径分隔符为/,第一个参数为SRC_PATH,第二个参数为DEST_PATH,其行为如下:

  • SRC_PATH指定文件
  • DEST_PATH不存在
  • 文件被保存到在DEST_PATH创建的文件中
  • DEST_PATH不存在且以/结尾
  • 错误条件:目标目录必须存在。
  • DEST_PATH存在且是文件
  • 目标将被源文件的内容覆盖
  • DEST_PATH存在且是目录
  • 文件将使用SRC_PATH的基本名复制到此目录中
  • SRC_PATH指定目录
  • DEST_PATH不存在
  • DEST_PATH被创建为目录,并将源目录的内容复制到此目录中
  • DEST_PATH存在且是文件
  • 错误条件:不能将目录复制到文件中
  • DEST_PATH存在且是目录
  • SRC_PATH不以/.结束(即:斜杠后跟点)
  • 源目录被复制到此目录中
  • SRC_PATH以/.结束(即:斜杠后跟点)
  • 源目录的内容被复制到此目录中
  • 该命令要求SRC_PATHDEST_PATH根据上述规则存在。如果SRC_PATH是本地的且是一个符号链接,那么默认复制的是符号链接,而不是目标。要复制链接目标而不是链接,请指定-L选项。

冒号(:)用作CONTAINER和其路径之间的分隔符。你还可以在本地机器上指定路径时使用:,例如file:name.txt。如果你在本地机器路径中使用:,你必须明确指定相对路径或绝对路径。

1.2 描述总结

docker cp 工具

docker cp工具允许你从容器复制文件到本地主机,或从本地主机复制文件到容器中。这不仅适用于正在运行的容器,而且适用于已停止的容器。

容器路径

docker cp默认容器路径是相对于容器的根目录(/),这意味着,
compassionate_darwin:/tmp/foo/myfile.txt
compassionate_darwin:tmp/foo/myfile.txt 是等效的。

本地路径

本地路径可以是相对路径或绝对路径。如果是相对路径,就相当于运行docker cp命令的工作目录。

复制的内容

  • 如果SRC_PATH指定一个文件,并且DEST_PATH不存在,docker cp会创建DEST_PATH并保存文件。
  • 如果SRC_PATH是一个文件,而DEST_PATH是一个已存在的文件,则DEST_PATH会被SRC_PATH的内容覆盖。
  • 如果SRC_PATH是一个文件,而DEST_PATH是一个目录,文件会被复制到DEST_PATH目录中,文件名保持不变。
  • 如果SRC_PATH是一个目录,docker cp会递归复制目录中的所有内容。

权限与所有权

复制过程会尽可能保留文件和目录的权限。默认情况下,所有权会被设置为目标处的用户和主要组。但是,使用-a选项会保留源文件的所有权。

符号链接

默认情况下,如果SRC_PATH是一个符号链接,docker cp会复制链接本身,而不是链接指向的文件。使用-L选项会复制链接指向的文件。

使用冒号

冒号(:)在docker cp命令中有特殊的意义。它用作容器名和容器内路径之间的分隔符。如果在本地路径中使用冒号,必须明确指定是相对路径还是绝对路径。

特殊情况与错误条件

  • 如果DEST_PATH以/结尾但不存在,这会导致错误,因为目标目录必须存在。
  • 如果SRC_PATH是目录,而DEST_PATH是已存在的文件,这也是一个错误条件,不能将目录复制到文件中。
  • docker cp不会为DEST_PATH创建不存在的父目录。

1.3 选项

Option

Short

Default

Description

–archive

-a

归档模式(复制所有uid/gid信息)。

–follow-link

-L

SRC_PATH中总是跟随符号链接。

–quiet

-q

复制过程中抑制进度输出。如果没有终端连接,进度输出会自动被抑制。

我使用的docker版本是20.10.24,已经没有-q这个参数了,你可以使用docker cp --help来查看你的版本是否包含。

2.使用示例

选择一个容器做示例,获取容器id

docker ps

我的容器id是:1fd731e7cc4e,这是我的工作目录下的信息

Dockerfile多个arg连着写 docker cp多个文件_相对路径

我现在我使用current.env作为示例,

宿主机复制文件到容器:

docker cp current.env 1fd731e7cc4e:/usr/local/openresty/

容器中即可看到文件:

Dockerfile多个arg连着写 docker cp多个文件_Dockerfile多个arg连着写_02

容器复制文件到宿主机:

docker cp 1fd731e7cc4e:/usr/local/openresty/resty.index ./

当前工作目录查看文件(ll或ls):

Dockerfile多个arg连着写 docker cp多个文件_Dockerfile多个arg连着写_03

带参数的示例

给logs创建一个软链接

ln -s target_file symlink

结果如下:

Dockerfile多个arg连着写 docker cp多个文件_相对路径_04

复制到容器自定目录下:

docker cp -a -L logslink 1fd731e7cc4e:/usr/local/openresty/

结果如下:

Dockerfile多个arg连着写 docker cp多个文件_符号链接_05

如果没有-L参数,复制的就是链接本身:

ln -s logs logslink2
docker cp -a logslink2 1fd731e7cc4e:/usr/local/openresty/

结果如下:

Dockerfile多个arg连着写 docker cp多个文件_Dockerfile多个arg连着写_06

不可复制文件解析示例:

Docker容器中一些特定的系统文件,例如位于/proc, /sys, /dev, 和 tmpfs的资源,以及用户在容器中创建的挂载点,是无法通过docker cp命令直接复制的。
使用docker cp命令时,如果将目标设为连字符-,那么它会将容器中所复制的文件的输出以tar流的形式流到标准输出(stdout)。对于在不实际将文件复制到本地文件系统的情况下进一步处理或过滤文件内容非常有用。
以挂载点/usr/local/openresty/nginx/logs为例:

docker cp 1fd731e7cc4e:/usr/local/openresty/nginx/logs/error.log - | tar x -O | grep "start"

结果如下:

Dockerfile多个arg连着写 docker cp多个文件_Dockerfile多个arg连着写_07

如果需要复制,官方提供了tardocker exec配合复制的案例,这里就不多示例了

官方文档地址: docker cp


生活是属于每个人自己的感受,不属于任何别人的看法 --余华《活着》