如何实现同一Docker卷关联不同容器的不同文件系统路径?
场景与问题
我在CentOS 7.9机器上使用Docker,以nginx镜像为例,该镜像有两个关键目录:
/usr/share/nginx/html:包含50x.html、index.html/usr/share/xml/fontconfig:包含fonts.dtd
root@f7990388c7d0:/# ls /usr/share/nginx/html/ 50x.html index.html root@f7990388c7d0:/# ls /usr/share/xml/fontconfig/ fonts.dtd
现有操作与问题
- 创建
my_volume卷并挂载到container1的/usr/share/nginx/html,验证文件正常同步:
[cloud_user@eb993010811c ~]$ docker volume create my_volume my_volume [cloud_user@eb993010811c ~]$ docker container run -d --name container1 -v my_volume:/usr/share/nginx/html nginx f7990388c7d0302db7f1135549bf0bb1a024256d9a89ebead306a6d775449514 [cloud_user@eb993010811c ~]$ docker volume inspect my_volume [ { "CreatedAt": "2022-11-09T14:46:38Z", "Driver": "local", "Labels": {}, "Mountpoint": "/var/lib/docker/volumes/my_volume/_data", "Name": "my_volume", "Options": {}, "Scope": "local" } ] [cloud_user@eb993010811c ~]$ sudo ls /var/lib/docker/volumes/my_volume/_data 50x.html index.html [cloud_user@eb993010811c ~]$ docker container exec -it container1 ls /usr/share/nginx/html 50x.html index.html [cloud_user@eb993010811c ~]$ docker container exec -it container1 ls /usr/share/xml/fontconfig fonts.dtd
- 将同一
my_volume挂载到container2的/usr/share/xml/fontconfig后,出现覆盖问题:
[cloud_user@eb993010811c ~]$ docker container run -d --name container2 -v my_volume:/usr/share/xml/fontconfig nginx 7ceec36b8c4d7d0eb172c1926d273d4e2e18b2cf509c8c5a18bf1302e98aedfc [cloud_user@eb993010811c ~]$ sudo ls /var/lib/docker/volumes/my_volume/_data 50x.html index.html [cloud_user@eb993010811c ~]$ docker container exec -it container2 ls /usr/share/xml/fontconfig 50x.html index.html [cloud_user@eb993010811c ~]$ docker container exec -it container1 ls /usr/share/xml/fontconfig fonts.dtd [cloud_user@eb993010811c ~]$ docker container exec -it container1 /bin/bash root@f7990388c7d0:/# ls /usr/share/nginx/html/ 50x.html index.html root@f7990388c7d0:/# ls /usr/share/xml/fontconfig/ fonts.dtd
结果:container2的/usr/share/xml/fontconfig被卷中的html文件覆盖,无法访问原有的fonts.dtd。我理解单卷挂载到不同路径的文件存在合理性问题,但仍想知道是否有方法实现需求,让一个卷可以对应不同路径的文件。
可行解决方案
1. 卷内分目录挂载
将卷划分为子目录,分别存放两个路径的文件,再对应挂载到容器的目标路径:
# 创建卷 docker volume create my_volume # 临时容器复制文件到卷的子目录 docker run --rm -v my_volume:/data nginx sh -c "mkdir -p /data/html /data/fontconfig && cp -r /usr/share/nginx/html/* /data/html/ && cp /usr/share/xml/fontconfig/fonts.dtd /data/fontconfig/" # 启动container1,挂载html子目录到对应路径 docker run -d --name container1 -v my_volume/html:/usr/share/nginx/html nginx # 启动container2,挂载fontconfig子目录到对应路径 docker run -d --name container2 -v my_volume/fontconfig:/usr/share/xml/fontconfig nginx
验证:两个容器将分别访问卷内对应子目录的文件,不会出现覆盖,且文件统一存储在my_volume卷中。
2. 使用Bind Mount替代Docker卷
直接利用宿主机目录存储文件,灵活性更高:
# 宿主机创建共享目录结构 sudo mkdir -p /opt/my_shared/html /opt/my_shared/fontconfig # 从临时容器复制文件到宿主机目录 docker run --rm -v /opt/my_shared:/host nginx sh -c "cp -r /usr/share/nginx/html/* /host/html/ && cp /usr/share/xml/fontconfig/fonts.dtd /host/fontconfig/" # 启动container1挂载宿主机html目录 docker run -d --name container1 -v /opt/my_shared/html:/usr/share/nginx/html nginx # 启动container2挂载宿主机fontconfig目录 docker run -d --name container2 -v /opt/my_shared/fontconfig:/usr/share/xml/fontconfig nginx
这种方式可直接在宿主机修改文件,无需通过容器操作,适合需要频繁调整文件的场景。
3. 构建自定义镜像
若需长期稳定使用,可构建自定义nginx镜像,将两个目录的内容整合到镜像内的固定路径,或修改nginx配置适配路径,但该方式不依赖卷共享,适合固定配置的场景。
内容的提问来源于stack exchange,提问作者Jason
相关产品推荐
相关产品推荐

