【问题标题】:How to mount volume from container to host in Docker?如何在 Docker 中将卷从容器挂载到主机?
【发布时间】:2021-01-13 19:55:01
【问题描述】:

我对 Docker 中的整个数据卷过程有疑问。基本上这里有两个 Dockerfile 和它们各自的运行命令:

Dockerfile 1 -

# Transmission over Debian
#
# Version 2.92

FROM debian:testing

RUN apt-get update \
    && apt-get -y install nano \
    && apt-get -y install transmission-daemon transmission-common transmission-cli \
    && mkdir -p /transmission/config /transmission/watch /transmission/download

ENTRYPOINT ["transmission-daemon", "--foreground"]
CMD ["--config-dir", "/transmission/config", "--watch-dir", "/transmission/watch", "--download-dir", "/transmission/download", "--allowed", "*", "--no-blocklist", "--no-auth", "--no-dht", "--no-lpd", "--encryption-preferred"]

命令 1 -

docker run --name transmission -d -p 9091:9091 -v C:\path\to\config:/transmission/config -v C:\path\to\watch:/transmission/watch -v C:\path\to\download:/transmission/download transmission  

Dockerfile 2 -

# Nginx over Debian
#
# Version 1.10.3

FROM debian:testing

RUN apt-get update \
    && apt-get -y install nano \
    && apt-get -y install nginx

EXPOSE 80 443

CMD ["nginx", "-g", "daemon off;"]

命令 2 -

docker run --name nginx -d -p 80:80 -v C:\path\to\config:/etc/nginx -v C:\path\to\html:/var/www/html nginx

所以,奇怪的是第一个 dockerfile 和命令按预期工作。 docker 守护程序将目录从容器安装到主机的位置。因此,我可以随意编辑配置文件,它们将在重新启动时保存到容器中。

但是,对于第二个 dockerfile 和命令,它似乎不起作用。我知道如果你去 Docker Volume 文档,它说卷安装只是为了单向,从主机到容器,但是传输容器如何按预期工作,而 Nginx 容器没有?

P:S - 我正在运行 Microsoft Windows 10 Pro Build 14393 作为我的主机和 Version 17.03.0-ce-win1 (10300) Channel: beta 作为我的 Docker 版本。

编辑 - 只是为了澄清。我正在尝试将文件从 Nginx 容器内部获取到主机。第一个容器(传输)通过使用数据卷在这方面起作用。但是,对于第二个容器(Nginx),它不想将挂载目录中的文件从容器内部复制到主机。其他一切正常,但它确实成功启动了。

【问题讨论】:

  • 什么“不起作用”?容器无法启动?本地文件是否出现在挂载目录中但未更新?挂载的目录中是否有任何内容?
  • @Matt 我正在尝试将文件从 Nginx 容器内部获取到主机。第一个容器(传输)通过使用数据卷在这方面起作用。但是,对于第二个容器(Nginx),它不想将挂载目录中的文件从容器内部复制到主机。其他一切正常,但它确实成功启动了。
  • 请用这些信息更新您的问题。

标签: docker


【解决方案1】:

Host volumes 不要从容器 > 主机复制数据。主机卷安装在容器/映像中的顶部,因此它们有效地将容器中的内容替换为主机上的内容。

A standard or "named" volume将现有数据从容器映像复制到新卷中。这些卷是通过在其 Dockerfile 中使用 VOLUME 命令或 docker 命令启动容器来创建的

docker run -v myvolume:/var/whatever myimage

默认情况下,这是存储在“本地”卷中的数据,“本地”位于 Docker 主机上。在您的情况下,它位于运行 Docker 的虚拟机上,而不是您的 Windows 主机上,因此您可能不容易访问。

您可能将空白目录中的传输自动生成文件误认为是副本?

如果您确实需要保留 VM 主机 > 容器映射,那么您可能必须手动复制数据:

docker create --name nginxcopy nginx
docker cp nginxcopy:/etc/nginx C:\path\to\config
docker cp nginxcopy:/var/www/html C:\path\to\html
docker rm nginxcopy

然后您可以将填充的主机目录映射到容器中,它们将具有图像附带的默认数据。

【讨论】:

  • 您能多解释一下标准卷吗? “将容器映像中的现有数据复制到新卷”是什么意思?
  • 我已经扩展了这个部分。基本上,当 docker 为 Dockerfile VOLUMEdocker run -v volume:/wherever 创建新卷时,它将使用容器映像中目标挂载点 (/wherever) 中已存在的任何内容填充该卷。这是您正在寻找的行为,但您没有在主机上指定位置并且它没有映射到 Windows。
  • 好吧,这更有意义,但我仍然对一件事感到困惑。为什么Transmission容器将文件复制到主机上的目录,而Nginx容器没有?
  • @Cat 尝试将所有配置移动到其他地方并再次启动容器。传输丢失时是否会重新创建配置?
  • 是的,确实如此。但是,这是一个全新的配置。这意味着它的设置与我移动的设置不同。
【解决方案2】:

主机卷不会像命名卷那样复制数据。但是,您可以创建一个执行绑定挂载的命名卷,然后它将具有任何其他命名卷的数据初始化属性。在主机卷上绑定挂载的唯一先决条件是该目录必须预先存在,docker 不会像使用主机卷那样为您创建它。以下是如何创建绑定挂载卷的三个不同示例:

  # create the volume in advance
  $ docker volume create --driver local \
      --opt type=none \
      --opt device=/home/user/test \
      --opt o=bind \
      test_vol

  # create on the fly with --mount
  $ docker run -it --rm \
    --mount type=volume,dst=/container/path,volume-driver=local,volume-opt=type=none,volume-opt=o=bind,volume-opt=device=/home/user/test \
    foo

  # inside a docker-compose file
  ...
  volumes:
    bind-test:
      driver: local
      driver_opts:
        type: none
        o: bind
        device: /home/user/test
  ...

因此,在您使用docker run 命令的示例中,您可以使用挂载语法:

docker run --name nginx -d -p 80:80 \
  --mount type=volume,dst=/etc/nginx,volume-driver=local,volume-opt=type=none,volume-opt=o=bind,volume-opt=device=/c/path/to/config \
  --mount type=volume,dst=/var/www/html,volume-driver=local,volume-opt=type=none,volume-opt=o=bind,volume-opt=device=/c/path/to/html \
  nginx

可能需要调整的唯一部分是 docker 在 HyperV 中运行的 Linux VM 内的 windows 路径名。

【讨论】:

    猜你喜欢
    • 2017-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-19
    • 1970-01-01
    • 2014-11-20
    相关资源
    最近更新 更多