【手搓 Docker 卷 volumes】从 `docker volume create` 到落盘位置的最后1公里

面向 Windows / macOS / Linux 三端,读完能自己找到卷、备份卷、甚至把它"迁"到另一台机器。


一、为什么要聊 Volume

容器="不可变基础设施"这一口号喊得响,可现实里没人敢把数据库、日志、上传目录直接塞进容器可写层------删容器即删库跑路。

Docker 给出三种外挂方式:

  1. Bind mount:把宿主机任意目录 -v 挂进去,简单暴力,却和宿主机路径强耦合。
  2. tmpfs:内存盘,重启即无,适合临时缓存。
  3. 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 只做两件事

  1. 在宿主机 /var/lib/docker/volumes/<name>(Win/mac 见第三节)生成 _data 目录。
  2. 把卷元信息写进 /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 盘,别傻翻。


四、卷的日常"四板斧"

  1. 起容器时自动创建
    docker run -v nginx-html:/usr/share/nginx/html nginx

    nginx-html 不存在,引擎会先 create 再挂载,免手写 create

  2. 只读挂载
    --mount type=volume,src=nginx-html,dst=/usr/share/nginx/html,ro=true

    适合把静态资源挂给多个副本,防误写。

  3. 预填充卷

    空卷挂到非空目录,Docker 会把容器目录内容拷贝进卷;若不想拷贝,加 volume-nocopy 选项。

  4. 备份 & 还原

    备份:

    bash 复制代码
    docker run --rm -v nginx-html:/data \
      -v ${PWD}:/backup alpine \
      tar czf /backup/nginx-html.tar.gz -C /data .

    还原:

    bash 复制代码
    docker run --rm -v nginx-html:/data \
      -v ${PWD}:/backup alpine \
      tar xzf /backup/nginx-html.tar.gz -C /data

    全程不依赖宿主机路径,放任意机器都能还原。


五、把卷"迁"到另一台主机

场景:开发机卷想搬到测试服务器。

  1. 导出

    bash 复制代码
    docker 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 .
  2. 拷贝 tgz 到目标机任意方式(scp、网盘、U 盘)。

  3. 目标机导入

    bash 复制代码
    docker 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

七、性能小贴士

  1. macOS 绑定挂载慢?

    把代码目录做成卷,而不是 -v /Users/xxx/project:/app 绑定,能躲开 osxfs 用户态文件系统,I/O 提升 3~8 倍。

  2. Windows 防杀毒扫描
    \\wsl$\docker-desktop-data 目录被 Windows Defender 实时扫描会拖慢数据库,可在"病毒威胁防护设置"里排除该路径。

  3. 卷驱动选错=白搭

    高并发写日志别用 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,团队新人再也不会问"数据库文件放哪了"。

相关推荐
聆风吟º9 小时前
CANN开源项目深度实践:基于amct-toolkit实现自动化模型量化与精度保障策略
运维·开源·自动化·cann
较劲男子汉12 小时前
CANN Runtime零拷贝传输技术源码实战 彻底打通Host与Device的数据传输壁垒
运维·服务器·数据库·cann
风流倜傥唐伯虎13 小时前
Spring Boot Jar包生产级启停脚本
java·运维·spring boot
Doro再努力13 小时前
【Linux操作系统10】Makefile深度解析:从依赖推导到有效编译
android·linux·运维·服务器·编辑器·vim
senijusene13 小时前
Linux软件编程:IO编程,标准IO(1)
linux·运维·服务器
忧郁的橙子.13 小时前
02-本地部署Ollama、Python
linux·运维·服务器
醇氧13 小时前
【linux】查看发行版信息
linux·运维·服务器
lpruoyu14 小时前
【Docker进阶-03】存储原理
docker·容器
No8g攻城狮14 小时前
【Linux】Windows11 安装 WSL2 并运行 Ubuntu 22.04 详细操作步骤
linux·运维·ubuntu
酷酷的崽79814 小时前
CANN 生态可维护性与可观测性:构建生产级边缘 AI 系统的运维体系
运维·人工智能