Windows 上 Docker 卷的最佳实践

问题描述 投票:0回答:2

我正在运行 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
2个回答
1
投票

最佳答案(由orderlyfashion找到):

使用环境变量。

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

如果您使用

docker volume create
创建卷,则可以在 compose 的顶级
volume
部分中指定它,然后使用卷的名称,后跟路径和每个容器中的访问权限,您就可以没有停止指定访问权限。

查看更多这里,具体

短语法使用通用的 [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 (命名卷来共享它)然后停止(因为它已经完成了它的主要过程)

命名卷现已初始化,可以共享到具有您想要的访问权限(

ro
rw
)的任何容器。

UPSIDES:一切都在docker卷中,易于备份 DOWNSIDES:数据在卷内重复。你会得到两倍相同量的数据,并且除非重做一次初始化,否则数据不会更新


0
投票

就我而言,我提前在 Linux 容器中创建了一个卷,然后尝试通过 docker compose 挂载它。

用通常的方式定义它:

volumes:
  data_volume:

它失败了,因为它没有重用我提前创建的相同卷,而是创建了一个新卷,但我的目标是重用我已经存储了一些数据的另一个卷。

解决方案是检查我创建的卷:

docker volume inspect data
[
    {
        "CreatedAt": "2024-03-22T15:58:06Z",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/data/_data",
        "Name": "data",
        "Options": null,
        "Scope": "local"
    }
]

现在在 docker compose 文件中,我可以使用

Mountpoint
:

引用我的卷
version: "3.3"
services:
  linuxbackend:
    network_mode: bridge
    build:
      context: ./
      dockerfile: Dockerfile
    volumes:
      - C:\\:/workspaces
      - /var/run/docker.sock:/var/run/docker.sock
      - /var/lib/docker/volumes/data/_data:/mnt/data
© www.soinside.com 2019 - 2024. All rights reserved.