【问题标题】:Best practice Docker volumes on WindowsWindows 上的最佳实践 Docker 卷
【发布时间】:2021-03-14 12:53:58
【问题描述】:

我正在运行 Windows 10,我想使用 docker-compose 将我主机的一些目录挂载到 docker 容器中。

假设我有一个包含图片的文件夹: D:\MyPictures

我想在 Docker 中创建一个卷,并将该卷挂载到不同的容器中,以便能够访问图片。 最好我只需要定义一次我的卷,以便我可以通过名称或类似名称来引用它(如果我以后想移动图片文件夹,我只有一个地方可以更新路径)。 如果我可以为每个容器指定容器是否具有读/写访问权限或仅具有读访问权限,那也很好。

如果我直接在服务下指定卷,我知道该怎么做:

myservice:
  volumes:
    - /c/MyPictures:/mount/path/in/container

但是,如果我移动我的图片,我将有多个位置来更新路径。

当阅读有关使用 docker volume create 创建卷的信息时,我似乎无法为每个容器指定读/写访问权限。

在 Windows 上实现这一目标的最佳和最简单的方法是什么?

  • 指定一次卷
  • 将其安装在不同的容器中
  • 每个容器的访问粒度

【问题讨论】:

    标签: docker docker-compose docker-volume


    【解决方案1】:

    最佳答案(由 orderlyfashion 找到):

    使用环境变量。

    1. 使用变量MY_PICTURES=/c/MyPictures 创建文件globals.env
    2. docker-compose.yml,在容器的卷部分下,安装为:- ${MY_PICTURES}:/my_pictures:ro
    3. docker-compose --env-file global.env up开头

    如果你用docker volume create创建了一个volume,那么你可以在compose的顶层volumesection中指定它,然后在每个容器中使用volume的名字加上路径和访问权限,您不会停止指定访问权限。

    查看更多here,特别是

    短语法使用通用的 [SOURCE:]TARGET[:MODE] 格式,其中 SOURCE 可以是主机路径或卷名。 TARGET 是挂载卷的容器路径。标准模式是只读的 ro 和读写的 rw(默认)。


    这样做的下一个问题是命名卷不能绑定到特定文件夹,这与绑定挂载相反。

    当您执行-v <hostPath>:<containerPath> 时,您会创建一个绑定挂载。它是挂载在容器文件系统中的主机文件系统中的特定文件夹,一切都很好,但它有一个缺点:它不能共享。

    当您添加volumes 顶级选项或执行docker volume create 时,您将创建一个命名卷。命名卷是可以跨容器共享的空间,但不能绑定到主机上的特定文件夹。但是,如果您将数据写入此卷,它会保留在其中,它是一个持久卷。

    所以问题是:如何用数据初始化这个卷?答案是将该卷安装在一个容器中,该容器将在该卷中写入数据。它并不优雅,而且有点令人费解,但这就是解决方案......

    如何做到这一点:

    在你的 docker-compose.yml 中,添加这个服务和卷:

    services:
      initializer:
        image: <someimage> #I use python:3.9-slim, could be a simple busybox
        command: cp -R /mnt/. /media/
        volumes:
          - ./somefolder:/mnt
          - data_volume:/media
        service_you_want_to_attach_volume_to:
          ...
          volumes:
            - data_volume:<some path>:ro #or rw, you can set the rights per container
          depends_on:
            - initializer
    
    volumes:
      data_volume:
    

    容器初始化程序将启动,在 /mnt 中挂载包含您想要的数据的文件夹,在 /media 中挂载命名卷,从 /mnt 复制数据(因此您要共享的数据) 到/media (共享它的命名卷) 然后停止(因为它已经完成了它的主进程)

    命名卷现在已初始化,可以共享给任何具有所需访问权限(rorw)的容器。

    UPSIDES : 一切都在一个 docker 卷中,易于备份 缺点:数据将在卷内复制。您将获得两倍的数据量,并且除非您重做初始化,否则数据不会更新

    【讨论】:

    • 好的。所以分为三个步骤。 1)docker volume create。 2) 在 docker-compose 中列出卷。 3) 参考 docker-compose 中服务配置中的卷。我不明白的是,我在哪里指定主机上的路径?对于第 1 步,它显示The built-in local driver on Windows does not support any options.,所以我看不到我如何在那里指定路径。对于第 2 步,我尝试了 my-pictures://c/MyPicturesmy-pictures://c/MyPictures:/my-pictures 和一堆不同的东西,但都是无效的。
    • 抱歉拖了这么久,我在回答中解释了过程
    • 对不起,我有一个想法,直到现在才有时间测试它。我通过使用变量想出了另一个解决方案。 1) 使用变量MY_PICTURES=/c/MyPictures 创建一个文件globals.env。 2) 在docker-compose.yml 中,在容器的卷部分下,挂载为:- ${MY_PICTURES}:/my_pictures:ro。 3) 以docker-compose --env-file global.env up 开头。这似乎满足了我的要求并且奏效了。你觉得这种方法有什么问题吗?在您的解决方案中,数据是否以某种方式重复?我不确定我是否完全理解复制步骤的工作原理。
    • 您的解决方案很棒:) 在我的解决方案中,创建了一个容器并将卷安装在其中。然后将数据复制到该卷中。之后,该卷可以由多个容器共享(无数据重复)。它比一个简单的变量要昂贵得多!
    • 好的。因此,如果我理解正确,我会看到您的解决方案有两个缺点,具体取决于用例。 1)数据重复。如果我有 50 GB 的图片,现在我在实际图片之上还有一个额外的 50 GB 卷。 2) 在我重新创建容器之前,我对原始文件夹所做的任何更改都不会复制到卷中。要么你用解决方案和一些关于差异的信息来修改你的答案,要么我可以做到。那我就接受了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-05
    • 2019-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-29
    相关资源
    最近更新 更多