如何解决Windows 上的最佳实践 Docker 卷
我运行的是 Windows 10,我想使用 docker-compose 将主机的一些目录挂载到 docker 容器中。
所以说我有一个包含图片的文件夹:
D:\MyPictures
我想在 Docker 中创建一个卷,并将该卷挂载到不同的容器中以便能够访问图片。 最好我只需要定义一次我的卷,这样我就可以通过名称或类似的名称来引用它(如果我以后想移动图片文件夹,我只有一个地方可以更新路径)。 如果我可以为每个容器指定容器是具有读/写访问权限还是仅具有读访问权限,那就太好了。
如果我直接在服务下指定卷,我知道该怎么做:
myservice:
volumes:
- /c/MyPictures:/mount/path/in/container
但是如果我移动我的图片,我会有多个地方来更新路径。
当阅读有关使用 docker volume create
创建卷的内容时,我似乎无法为每个容器指定读/写访问权限。
在 Windows 上实现这一目标的最佳和最简单的方法是什么?
- 一次指定一个卷
- 将其安装在不同的容器中
- 每个容器的访问粒度
解决方法
最佳答案(由 orderlyfashion 找到):
使用环境变量。
- 使用变量
globals.env
创建一个文件MY_PICTURES=/c/MyPictures
- 在
docker-compose.yml
中,在容器的卷部分下,挂载为:- ${MY_PICTURES}:/my_pictures:ro
- 以
docker-compose --env-file global.env up
开头
如果使用 docker volume create
创建卷,则可以在 compose 的顶级 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 (共享它的命名卷) 然后停止 (因为它已经完成了它的主进程)
命名卷现已初始化,可以共享给具有所需访问权限(ro
或 rw
)的任何容器。
UPSIDES:一切都在一个docker卷中,易于备份 缺点:数据将在卷内复制。你会得到两倍相同数量的数据,除非你重新初始化,否则数据不会更新