从 Docker 容器复制文件到主机

Isaac Tony 2023年1月30日 2022年4月20日
  1. 使用 docker cp 将文件从 Docker 容器复制到主机
  2. 使用 Docker Mounts 将文件从 Docker 容器复制到主机
  3. 使用 COPY 将文件从 Docker 容器复制到主机
从 Docker 容器复制文件到主机

在 Docker 1.8 之前,我们只能将文件从容器复制到主机。但是,随着容器变得更加流行,将文件复制到容器中或从容器中复制文件已成为必要。

我们可能想要从 docker 容器复制文件的常见原因之一是与我们的团队成员共享日志文件。但是,不允许复制/dev/proc/systmpfs 下的资源等敏感信息。

本文将讨论如何使用 DockerFile、docker cp 命令从 Docker 容器中复制文件,并将目录作为卷挂载到主机。

这需要正确安装和配置 Docker 和 Docker 容器。这适用于 Linux 和 WSL 环境。

使用 docker cp 将文件从 Docker 容器复制到主机

docker cp 命令是我们可以用来将文件和目录以及从主机复制到 docker 容器的最简单方法之一。我们将使用 Ubuntu 20.4.5 和当时最新版本的 Docker,即 19.03。

语法:

$ docker cp [OPTIONS] CONTAINER: SRC_PATH DEST_PATH|-

其中,

  • SRC_PATH 指定我们要复制的文件在主机上的源路径。
  • DEST_PATH 是在容器上存储文件的目标路径。

使用此命令,我们可以通过交换参数 SRC_PATHDEST_PATH 来将文件复制到容器中或从容器中复制文件。此命令的一个优点是我们可以将文件和目录复制到正在运行或已停止的容器中或从中复制。

docker cp 命令类似于 Unix cp -a;因此,这意味着它还递归地复制目录。此外,该命令还假定容器的所有路径都相对于根目录。

我们将首先创建我们的目标容器;因此,我们还需要一个镜像。我们将使用 Docker 注册表中提供的官方 Ubuntu 映像。

$ docker pull ubuntu

然后,我们将以分离和交互模式创建一个 docker 容器。这允许我们的容器在后台运行。

$ docker run -it -d ubuntu
e10b4a7bbc59131d30492a87dd70b8ea74fa686ed5036ec918b6596fc83efe2b

使用 exec 命令,我们将使用命令 docker exec-it 标志运行交互式 SSH 会话。这将允许我们在容器内交互地运行命令。

要创建一个简单的文本文件,我们将导航到 /usr/share 文件夹。

我们将首先使用相应的容器 ID 进入容器。

$ docker exec -it e10b4a7bbc59 /bin/bash
root@e10b4a7bbc59:/#

我们将导航容器内的文件夹 /usr/share/ 以创建我们的文本文件。

$ docker exec -it e10b4a7bbc59 /bin/bash
root@e10b4a7bbc59:/# cd usr
root@e10b4a7bbc59:/usr# cd share
root@e10b4a7bbc59:/usr/share#

我们将使用 touch 命令创建一个名为 new_file.txt 的文件。我们将很快将此文件从该容器复制到我们的主机。

因此,最好记下存储文件的目录,因为我们将在将文件复制到主机时使用该位置。

root@e10b4a7bbc59:/usr/share# touch new_file.txt

要验证我们是否已创建文件,请运行 ls 命令列出此目录中的所有文件,如下所示。

root@e10b4a7bbc59:/usr/share# ls
adduser      bash-completion  debianutils  dpkg  keyrings  man           pam          polkit-1
apport       bug              dict         gcc   libc-bin  menu          pam-configs  sensible-utils
base-files   common-licenses  doc          gdb   lintian   misc          perl5        tabset
base-passwd  debconf          doc-base     info  locale    new_file.txt  pixmaps      terminfo

现在我们已经成功地在容器中创建了一个文件,我们想将这个文件从这个容器复制到我们的主机 - 使用 exit 命令从容器退出到主 shell。

我们将在终端中运行 docker cp 命令并将 new_file.txt 复制到主机的目录中。但是,我们首先需要注意三个重要的事情:

  • 容器标识;
  • 目标文件在容器中的位置;
  • 我们将复制文件的主机中的目标目录。
$ docker cp e10b4a7bbc59:/usr/share/new_file.txt ./new_file.txt

通过执行该命令,我们已成功将 new._file.txt 复制到主机。我们可以通过在该特定文件夹中运行 ls 命令来验证这一点。

isaac@DESKTOP-HV44HT6:~/isaac$ ls
adduser      bash-completion  debianutils  dpkg  keyrings  man     `new_file.txt`  pixmaps         terminfo
apport       bug              dict         gcc   libc-bin  menu    pam           polkit-1
base-files   common-licenses  doc          gdb   lintian   misc    pam-configs   sensible-utils
base-passwd  debconf          doc-base     info  locale    my-app  perl5         tabset

使用 Docker Mounts 将文件从 Docker 容器复制到主机

我们还可以使用 docker mounts 将文件从 docker 容器复制到主机。

绑定挂载是最早的解决方案之一,它允许我们通过将 docker 容器挂载到主机系统上的目录来持久化数据。

绑定挂载允许我们通过引用目标目录的绝对文件路径来引用确切的目录。除了将文件从容器复制到主机之外,我们还可以创建依赖于主机系统目录的服务。

要创建 docker 挂载,我们可以在创建 docker 容器时使用 -v--mount 标志。除了这个标志之外,我们还将指定我们想要映射到 docker 容器上的目录的主机上的目录。

这种方法通常是首选,因为我们可以在 docker 容器内创建多个挂载。我们还可以创建目录来从多个容器传输文件。

要将我们的目录挂载到 docker 容器,我们必须指定以下字段,这些字段应始终以正确的顺序由冒号分隔。这些包括:

  • 我们要挂载的主机目录的路径;
  • 我们应该挂载该目录的容器中目录的路径;
  • 其他可选选项如 ro 指定只读模式。

语法:

docker run -t -i -v <host_dir>:<container_dir

在下面的示例中,我们使用 Ruby 官方镜像来创建容器并将本地目录挂载到容器上的目录中。完成此操作后,我们可以轻松地将文件从容器复制到本地目录,反之亦然。

$ docker run -it -v $HOME/Desktop/new_container:/new_container --name new_container ruby bash
root@7a00af9d4d96:/#

我们可以轻松地在 docker 容器和主机目录之间复制文件。另外,请注意,在主机目录中创建的文件将自动在挂载到主机的 docker 容器目录中可用。

使用 COPY 将文件从 Docker 容器复制到主机

当使用 docker 文件创建 docker 镜像时,我们还可以使用 COPY 命令在 docker 主机和容器之间复制文件。

语法:

COPY <SRC> <DEST>

在下面的 DockerFile 中,我们将 ./app.py 指定为源目录,将 /var/www/app.py 指定为目标目录。

#  base image
FROM python

# Set your working directory
WORKDIR /var/www/

# Copy the necessary filesls
COPY ./app.py /var/www/app.py
COPY ./requirements.txt /var/www/requirements.txt

# Install the necessary packages
RUN pip install -r /var/www/requirements.txt

# Run the app
ENTRYPOINT ["echo", "Hello, Developer"]

这个 DockerFile 创建一个简单的 Flask 应用程序的镜像,该应用程序在控制台上打印一条消息。

Author: Isaac Tony
Isaac Tony avatar Isaac Tony avatar

Isaac Tony is a professional software developer and technical writer fascinated by Tech and productivity. He helps large technical organizations communicate their message clearly through writing.

LinkedIn

相关文章 - Docker Container