Docker 数据卷 Volume

容器被删除后,它在可写层写下的数据会一并消失。数据卷(Volume)是 Docker 管理的持久化存储,独立于容器存在,专为解决「容器没了、数据还在」的问题。

为什么数据要持久化

三种数据挂载方式对比 数据库文件、日志、上传内容都需要长期保存:容器可以随时删除重建(升级镜像、迁移主机),数据却不能丢。把数据放进卷里,重建容器时挂上同一个卷即可无缝衔接。

创建与查看卷

卷由 Docker 统一管理,先建后用:

docker volume create mydata    # 创建名为 mydata 的卷
docker volume ls               # 输出:DRIVER    VOLUME NAME / local     mydata
docker volume inspect mydata   # 查看详情,Mountpoint 指向宿主机上的实际存储目录

卷的实际内容存放在宿主机 /var/lib/docker/volumes/ 下,一般不需要直接操作该目录。

把卷挂进容器

docker run 用 -v 把「卷名:容器内路径」挂载进容器,MySQL 数据落卷是经典用法:

docker run -d --name mydb \
  -v mysql-data:/var/lib/mysql \
  -e MYSQL_ROOT_PASSWORD=123456 mysql:8

删除容器再重建,只要挂同一个卷,数据仍然在:

docker rm -f mydb
docker run -d --name mydb2 -v mysql-data:/var/lib/mysql mysql:8
docker exec mydb2 ls /var/lib/mysql   # 输出:原有数据文件依然存在

容器间共享卷

多个容器挂载同一个卷即可互相共享数据;--volumes-from 是老用法,直接继承另一个容器的挂载配置:

docker run -d --name app1 -v shared-html:/usr/share/nginx/html nginx:alpine
docker run -d --name app2 -v shared-html:/usr/share/nginx/html nginx:alpine
docker exec app1 sh -c 'echo hi > /usr/share/nginx/html/a.html'
docker exec app2 cat /usr/share/nginx/html/a.html
# 输出:hi(app2 读到了 app1 写入的内容)

docker run -d --name app3 --volumes-from app1 nginx:alpine   # 复用 app1 的全部挂载

删除卷要小心

卷不会随容器自动删除,删容器时带 -v 或单独删除:

docker rm -v app1               # 删除容器的同时删除它关联的匿名卷
docker volume rm shared-html    # 显式删除命名卷(须先确保没有容器引用)
docker volume prune             # 清理所有未被使用的卷(谨慎执行!)

删除命名卷前务必确认数据不再需要,否则难以找回。

命名卷与 bind mount 的区别一句话

命名卷由 Docker 在自己的目录中管理,便于备份与迁移;bind mount 则直接把宿主机任意路径映射进容器(下一章详解)。持久化重要数据时优先用命名卷。

小结

数据持久化的标准做法:docker volume create 建卷 → docker run -v 卷名:容器路径 挂载 → 容器重建数据不丢;删除容器用 rm -v、清理用 volume prune 时,都要先确认数据是否还需要。

笔记加载中…