深色模式
Docker 卷与数据持久化
概述
容器删了,数据为什么有时还在,有时却一起没了,这是 Docker 里很典型的迷惑现场。问题不在 Docker 反复无常,而在于数据到底是写进了容器自身文件系统,还是落在了卷或宿主机挂载路径里。
卷相关内容真正要先讲清的,不是命令名,而是“数据放在哪里、跟谁一起生命周期变化”。只要这层想明白,命名卷、绑定挂载、匿名卷就没那么绕。
先记住容器文件系统不是长期存储方案
如果应用直接把数据写进容器内部文件系统,而没有卷或挂载参与,那么容器删除后,这部分数据通常也就跟着一起没了。
所以数据库、上传文件、缓存目录、配置持久化这些场景,默认都要先考虑数据挂载方式。不要等删完容器才想起来“原来数据一直住在里面”。
三种常见挂载方式
Docker 日常最常见的挂载方式有三种:
- 命名卷
- 绑定挂载
- 匿名卷
命名卷
命名卷是最常见、也最适合长期数据的做法之一。
例如:
sh
docker volume create db-data
docker run -d --name db -v db-data:/var/lib/mysql mysql:8.4它的特点是:
- 卷有明确名字,便于管理
- 生命周期和容器分开
- 适合数据库、缓存、应用数据目录这类持久化场景
对很多服务来说,命名卷通常是默认优先考虑的方案。
绑定挂载
绑定挂载是把宿主机上的一个明确路径挂进容器:
sh
docker run -d --name app -v "$PWD":/app node:22它更适合这类场景:
- 本地开发时把源码目录挂进容器
- 宿主机已经有明确的配置目录或数据目录
- 需要直接在宿主机上查看和编辑文件
它的优点是直观,缺点也很直观:更依赖宿主机目录结构,迁移性不如命名卷。
匿名卷
匿名卷会挂一个卷,但不给它显式命名:
sh
docker run -d -v /var/lib/mysql mysql:8.4它不是不能用,而是管理起来不如命名卷直观。只要项目需要长期维护,匿名卷通常都不是最优先的选择。
怎么选更稳
- 数据库、缓存、长期状态数据:优先命名卷
- 本地开发源码挂载、宿主机配置目录:优先绑定挂载
- 不想关心名字的临时场景:才考虑匿名卷
很多人真正想问的其实不是“volume 和 bind mount 有什么定义区别”,而是“我这个场景应该怎么选”。大多数时候,答案就是上面这三行。
卷和容器生命周期不是一回事
这是另一条特别值得先记住的线。
删除容器:
sh
docker rm db通常并不会顺手把命名卷一起删掉。也正因为如此,重新创建容器后,数据还能继续挂回来。
这既是优点,也是风险点。优点是数据不会因为重建容器就丢;风险点是想彻底清理环境时,别只删容器不删卷。
常用卷命令
创建卷:
sh
docker volume create app-data查看卷:
sh
docker volume ls查看卷详情:
sh
docker volume inspect app-data删除卷:
sh
docker volume rm app-data清理未使用卷:
sh
docker volume prune这几个命令已经覆盖了大部分日常卷管理需求。
三个典型场景
数据库数据目录
数据库最典型的挂载对象就是数据目录,例如 MySQL 的 /var/lib/mysql。这类目录通常优先用命名卷,因为重点是稳定持久,不是方便手改。
本地开发源码目录
开发阶段常常会把宿主机项目目录直接 bind mount 到容器里。这样改代码后,容器内能立刻看到变更,不需要每次都重新构建镜像。
应用配置或证书目录
如果配置文件本来就由宿主机统一维护,或者证书续期流程跑在宿主机上,绑定挂载通常会比命名卷更直接。
一句够用的判断
问自己两个问题,通常就够了:
- 数据是否需要跟容器生命周期分离。
- 这份数据是否需要在宿主机上直接看见和修改。
第一个问题决定要不要挂载,第二个问题大多能决定该选命名卷还是绑定挂载。
