【手搓 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,团队新人再也不会问"数据库文件放哪了"。

相关推荐
深耕AI2 小时前
【Docker Desktop for Windows】 两个 volumes 目录的区别
windows·docker·容器
鸠摩智首席音效师2 小时前
如何在 Linux 中使用 fallocate 命令 ?
linux·运维·服务器
雨大王5122 小时前
如何选择汽车制造数字化服务商?关键指标与实战案例解析
大数据·运维·人工智能
QT 小鲜肉2 小时前
【Linux命令大全】001.文件管理之split命令(实操篇)
linux·运维·服务器·网络·笔记
是垚不是土2 小时前
TDengine脚本备份方案:全库/单库备份与飞书通知
大数据·运维·数据库·飞书·时序数据库·tdengine
yannan201903132 小时前
简述kubernetes(k8s)
云原生·容器·kubernetes
码农小白猿2 小时前
提升压力容器改造方案报告标准条款审核效率,IACheck助力合规与安全
运维·人工智能·安全·ai·自动化·iacheck
oMcLin2 小时前
Linux 容器技术实战:从 Docker 到 Podman 的无 root 权限部署
linux·docker·podman
Tipriest_2 小时前
ubuntu快速查看一个apt包的描述信息和依赖等
linux·运维·ubuntu·apt