我正在运行 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
部分中指定它,然后使用卷的名称,后跟路径和每个容器中的访问权限,您就可以没有停止指定访问权限。
查看更多这里,具体
短语法使用通用的 [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:数据将在卷内重复。你会得到两倍相同量的数据,并且除非重做一次初始化,否则数据不会更新
就我而言,我提前在 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