面向 Windows / macOS / Linux 三端,读完能自己找到卷、备份卷、甚至把它"迁"到另一台机器。
一、为什么要聊 Volume
容器="不可变基础设施"这一口号喊得响,可现实里没人敢把数据库、日志、上传目录直接塞进容器可写层------删容器即删库跑路。
Docker 给出三种外挂方式:
- Bind mount:把宿主机任意目录
-v挂进去,简单暴力,却和宿主机路径强耦合。 - tmpfs:内存盘,重启即无,适合临时缓存。
- Volume:Docker 官方推荐的"一等公民",生命周期与容器解耦,跨平台行为一致,还能用驱动插件把数据扔到 NFS、S3、Ceph。
docker volume create 就是 Volume 的"入口命令",但很多人止步于"能 create 就行",结果连卷文件在哪都找不到,更别提备份、迁移、排障。下文把它拆成四步:创建 → 落盘 → 使用 → 迁移。
二、create 到底做了什么
命令极简:
bash
docker volume create --driver local \
--opt type=none \
--opt device=/mnt/fastssd \
--opt o=bind \
fast-ssd-volume
拆解:
--driver local默认缺省,表示用本地文件系统。--opt可传底层挂载参数,像type=none+o=bind就能让卷指向你指定的一块盘,实现"把数据库扔到 SSD"这种需求。- 不传任何参数时,Docker 会生成一串 UUID 作为卷名,也可像上方显式命名。
create 成功瞬间,Docker 只做两件事:
- 在宿主机
/var/lib/docker/volumes/<name>(Win/mac 见第三节)生成_data目录。 - 把卷元信息写进
/var/lib/docker/volumes/<name>/opts.json(驱动、挂载参数等)。
卷立即可被任意容器通过 -v <name>:/path/in/container 或 --mount type=volume,src=<name>,dst=/path 挂载,即使容器被删,_data 依旧存在。
三、三平台落盘路径速查
| 系统 | 引擎类型 | 真实路径 |
|---|---|---|
| Linux | 原生 | /var/lib/docker/volumes/<卷名>/_data |
| macOS | Docker Desktop | ~/Library/Containers/com.docker.docker/Data/vms/0/data/docker/volumes/<卷名>/_data(在虚拟机内部,需 screen 进 VM 或 docker run -v /:/host ... 拐出来) |
| Windows 10/11 | Docker Desktop + WSL2 | \\wsl$\docker-desktop-data\version-pack-data\community\docker\volumes\<卷名>\_data(Win10 1903 以下无 \\wsl$,需先进 WSL 再 cd /var/lib/docker/volumes) |
在win10上,我们输入 \\wsl$或者 \\wsl.localhost就会看到如下界面:

进来后,就会看到:

搜素volums就会看到:

第1个目录是 \\wsl.localhost\docker-desktop\mnt\docker-desktop-disk\data\docker\volumes,
第2个目录是 \\wsl.localhost\docker-desktop\tmp\docker-desktop-root\var\lib\docker\volumes。
点击其中的第1个目录,就会看到:

关于两个目录的区别介绍,参见文章。
快速定位命令(三端通用):
bash
docker volume inspect my-volume --format '{{.Mountpoint}}'
拿到路径后,Linux/mac 直接 sudo ls;Windows 在 资源管理器地址栏手敲 \\wsl$\docker-desktop-data\... 即可浏览------不会自动出现在 C 盘,别傻翻。
四、卷的日常"四板斧"
-
起容器时自动创建
docker run -v nginx-html:/usr/share/nginx/html nginx若
nginx-html不存在,引擎会先 create 再挂载,免手写 create。 -
只读挂载
--mount type=volume,src=nginx-html,dst=/usr/share/nginx/html,ro=true适合把静态资源挂给多个副本,防误写。
-
预填充卷
空卷挂到非空目录,Docker 会把容器目录内容拷贝进卷;若不想拷贝,加
volume-nocopy选项。 -
备份 & 还原
备份:
bashdocker run --rm -v nginx-html:/data \ -v ${PWD}:/backup alpine \ tar czf /backup/nginx-html.tar.gz -C /data .还原:
bashdocker run --rm -v nginx-html:/data \ -v ${PWD}:/backup alpine \ tar xzf /backup/nginx-html.tar.gz -C /data全程不依赖宿主机路径,放任意机器都能还原。
五、把卷"迁"到另一台主机
场景:开发机卷想搬到测试服务器。
-
导出
bashdocker volume create nginx-html-backup docker run --rm -v nginx-html:/from -v nginx-html-backup:/to alpine cp -a /from/. /to/ docker run --rm -v nginx-html-backup:/backup -v $(pwd):/host alpine tar czf /host/nginx-html.tgz -C /backup . -
拷贝 tgz 到目标机任意方式(scp、网盘、U 盘)。
-
目标机导入
bashdocker volume create nginx-html docker run --rm -v nginx-html:/data -v $(pwd):/host alpine tar xzf /host/nginx-html.tgz -C /data
Volume 驱动不同怎么办?
若源机用 local,目标机想迁到 NFS,只需第 3 步改成:
bash
docker volume create --driver nfs \
--opt nfsaddr=10.0.0.20 \
--opt device=:/docker/nginx-html \
nginx-html
再把 tar 内容解压进 NFS 目录即可,应用层零改动。
六、匿名卷 & 自动清理
docker run -v /data mysql:8 这种只写容器路径、没给名字的,会生成"匿名卷",长这样:
a3f1e9c1d3e2f741b2c6d.../_data
容器 docker rm 时加 --rm 会自动把匿名卷带走;不加就残留。
定期打扫:
bash
docker volume prune # 删除所有"未被挂载"的匿名/命名卷,危险但省空间
docker system df -v # 先查看各卷占用,再决定是否 prune
七、性能小贴士
-
macOS 绑定挂载慢?
把代码目录做成卷,而不是
-v /Users/xxx/project:/app绑定,能躲开osxfs用户态文件系统,I/O 提升 3~8 倍。 -
Windows 防杀毒扫描
\\wsl$\docker-desktop-data目录被 Windows Defender 实时扫描会拖慢数据库,可在"病毒威胁防护设置"里排除该路径。 -
卷驱动选错=白搭
高并发写日志别用
local+机械盘,换nfs+SSD 或block驱动;只读配置类文件随便local即可。
八、一条命令总结
bash
docker volume create myvol # 创建
docker run -v myvol:/data myapp # 使用
docker volume inspect myvol # 找路径
tar czf myvol.tgz -C /var/lib/docker/volumes/myvol/_data . # 备份
把这四步写进你的 README,团队新人再也不会问"数据库文件放哪了"。