Docker存储数据卷
Docker 系列(五):数据持久化 Volume 与 Bind Mount
2026年7月24日 · 12 分钟
为什么需要数据持久化
回顾第三篇的原理:容器 = 只读镜像层 + 一个可写层,而可写层随容器删除而消失。
这意味着一个致命问题:
docker run -d --name db postgres # 跑个数据库
# ... 写入了一堆重要数据 ...
docker rm -f db # 容器删了
# 💥 数据全没了!
对于数据库、上传文件、日志这类需要长期保存的数据,我们必须把它们存到容器之外。 Docker 提供了三种方式。
三种数据挂载方式
┌──────────────────────────────────────────────┐
│ 宿主机 │
│ │
│ /var/lib/docker/volumes/ ← Volume(Docker 管理)│
│ /home/user/data/ ← Bind Mount(你指定) │
│ │
│ 内存 ← tmpfs(不落盘) │
└──────────────────────────────────────────────┘
| 类型 | 存储位置 | 谁管理 | 适用场景 |
|---|---|---|---|
| Volume(卷) | Docker 专属目录 | Docker | 生产首选,数据库、持久数据 |
| Bind Mount(绑定挂载) | 你指定的宿主机路径 | 你自己 | 开发时挂源码、挂配置文件 |
| tmpfs | 内存 | Docker | 临时敏感数据,不需落盘 |
一、Volume(推荐)
Volume 由 Docker 统一管理,存放在 Docker 的专属目录,你不用关心具体物理路径。
# 创建一个卷
docker volume create mydata
# 查看所有卷
docker volume ls
# 挂载到容器:-v 卷名:容器内路径
docker run -d --name db -v mydata:/var/lib/postgresql/data postgres
# 查看卷详情(包括真实路径)
docker volume inspect mydata
# 删除卷(容器还在用时删不掉)
docker volume rm mydata
即使 docker rm -f db 删掉容器,mydata 卷里的数据依然安在。下次挂载同一个卷,
数据原封不动。
二、Bind Mount(绑定挂载)
直接把宿主机上的某个目录/文件挂进容器。开发时特别有用——改本机代码,容器里立刻生效。
# -v 宿主机绝对路径:容器内路径
docker run -d -p 8080:80 -v /home/user/site:/usr/share/nginx/html nginx
# Windows PowerShell 里用当前目录
docker run -d -p 8080:80 -v ${PWD}:/usr/share/nginx/html nginx
现在你在宿主机 /home/user/site 里改任何文件,刷新网页就能看到——非常适合本地开发。
只读挂载:加
:ro后缀让容器无法修改,如-v /host/config:/app/config:ro, 常用于挂配置文件。
三、-v 与 --mount 两种语法
老语法 -v 简洁,新语法 --mount 更明确(推荐脚本/生产用):
# -v 简写
docker run -v mydata:/data ...
# --mount 显式写法,含义一目了然
docker run --mount type=volume,source=mydata,target=/data ...
docker run --mount type=bind,source=/host/path,target=/data ...
实战:给 PostgreSQL 持久化数据
# 1. 创建专用卷
docker volume create pgdata
# 2. 启动数据库,挂载卷 + 设置密码
docker run -d --name pg \
-e POSTGRES_PASSWORD=secret \
-p 5432:5432 \
-v pgdata:/var/lib/postgresql/data \
postgres:16
# 3. 连进去建张表、写点数据(略)
# 4. 模拟"服务器重装":删掉容器
docker rm -f pg
# 5. 用同一个卷重新启动
docker run -d --name pg \
-e POSTGRES_PASSWORD=secret \
-p 5432:5432 \
-v pgdata:/var/lib/postgresql/data \
postgres:16
# ✅ 之前的表和数据都还在!
数据备份与恢复
Volume 的数据可以借助一个临时容器打包备份:
# 备份 pgdata 卷到当前目录的 backup.tar
docker run --rm \
-v pgdata:/data \
-v ${PWD}:/backup \
alpine tar czf /backup/backup.tar -C /data .
# 恢复:把 backup.tar 解压回一个卷
docker run --rm \
-v pgdata:/data \
-v ${PWD}:/backup \
alpine tar xzf /backup/backup.tar -C /data
思路很巧妙:起一个临时 alpine 容器,同时挂上「数据卷」和「宿主机目录」,用 tar 在两者之间搬运数据。
本篇小结
- 容器可写层随删除消失,持久数据必须挂到容器之外。
- Volume:Docker 管理,生产首选;Bind Mount:挂宿主机路径,开发挂源码/配置; tmpfs:内存临时数据。
-v 卷名:容器路径用卷,-v 宿主路径:容器路径是绑定挂载,:ro设只读。- 数据库务必挂卷,否则重建容器数据全丢;可用临时容器 + tar 做备份恢复。
数据能存了,下一篇解决容器之间怎么「通信」——Docker 网络。