Docker数据持久化之如何让新容器同步旧数据详解
作者:一勺菠萝丶
适合人群:刚接触 Docker 的 Java / 后端开发者
目标:彻底理解 -v 数据卷的作用、数据保存机制,以及容器删除后数据为什么不丢
一、Docker 的容器与数据之间的关系
我们先来理解一个关键概念:
Docker 容器 ≠ 数据库本身。
可以把 Docker 想象成一个“小房子”:
- 房子里装着程序(比如 MySQL、Redis);
- 数据(比如数据库表)其实放在房子里面的“储物柜”里。
当你执行:
docker run -di --name mysql8.0 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root mysql:8.0
你只是建了个房子(容器),而数据默认存在房子里面的 /var/lib/mysql 目录下。
问题是:
当你把这个容器删掉时(docker rm -f mysql8.0),房子和里面的数据储物柜都会一起被“炸掉”,数据全没。
二、解决办法:用-v数据卷挂载
Docker 提供了一个“外 挂储物柜”的功能,叫 数据卷(Volume)。
举个例子:
docker run -di \ --name=mysql8.0 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD=root \ -v ~/docker/mysql/data:/var/lib/mysql \ mysql:8.0
这里的 -v 参数代表:
Mac宿主机路径 : 容器内部路径
即:
- 你的 Mac 上的
~/docker/mysql/data文件夹 - 实际上挂载到了容器里的
/var/lib/mysql
这意味着:
不管容器如何删、重建,~/docker/mysql/data 的内容都不会被删除,数据会一直保留在宿主机上。
三、验证实验:删容器后数据还在!
下面我们来做个小实验:
Step 1. 创建容器
docker run -di \ --name=mysql8.0 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD=root \ -v ~/docker/mysql/data:/var/lib/mysql \ mysql:8.0
Step 2. 进入容器创建一个数据库
docker exec -it mysql8.0 mysql -uroot -proot CREATE DATABASE testdb;
Step 3. 删除容器
docker rm -f mysql8.0
Step 4. 查看宿主机目录
ls ~/docker/mysql/data
你会看到很多 .ibd、.frm、testdb 文件夹还在。
说明数据没有被删除!
四、重新创建容器,数据还能“复活”!
现在我们重新启动一个新容器,但继续挂载同一个路径:
docker run -di \ --name=mysql_new \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD=root \ -v ~/docker/mysql/data:/var/lib/mysql \ mysql:8.0
然后进入新容器:
docker exec -it mysql_new mysql -uroot -proot SHOW DATABASES;
你会惊喜地发现 ——上次创建的 testdb 数据库还在!
五、原理解释:为什么新容器能同步旧数据?
这是因为:
-v参数让容器内部的/var/lib/mysql与宿主机的文件夹建立了“实时映射关系”;- 容器只是“使用”那里的数据文件,并不会直接拥有;
- 删除容器只会删除容器本身的镜像层,不会影响宿主机的文件。
换句话说:
数据卷是“独立存在的外部存储”,容器只是临时使用它。
六、同样适用于 Redis、Elasticsearch 等服务
| 服务 | 挂载命令 | 容器内默认路径 | 推荐宿主机路径 |
|---|---|---|---|
| MySQL | -v ~/docker/mysql/data:/var/lib/mysql | /var/lib/mysql | ~/docker/mysql/data |
| Redis | -v ~/docker/redis/data:/data | /data | ~/docker/redis/data |
| Elasticsearch | -v ~/docker/es/data:/usr/share/elasticsearch/data | /usr/share/elasticsearch/data | ~/docker/es/data |
| Jenkins | -v ~/docker/jenkins:/var/jenkins_home | /var/jenkins_home | ~/docker/jenkins |
| MinIO | -v ~/docker/minio/data:/data | /data | ~/docker/minio/data |
这些路径同理:只要挂载过,再建容器挂载相同路径 → 数据自然“同步回来”。
七、额外提示:查看挂载信息
想看某个容器的挂载状态:
docker inspect 容器名 | grep Mounts -A 10
可以看到类似:
"Mounts": [
{
"Type": "bind",
"Source": "/Users/yourname/docker/mysql/data",
"Destination": "/var/lib/mysql"
}
]
这就说明你的数据卷挂载成功。
八、小白总结一图流
无 -v 挂载:
[容器]——数据放在容器内(删容器=删数据)
有 -v 挂载:
[容器]←→[宿主机文件夹](删容器≠删数据)
重新启动时:
新容器 ←→ [同一个宿主机路径] → 数据自动同步回来 ✅
九、日常使用建议
| 场景 | 建议做法 |
|---|---|
| 本地开发 | 一定要挂载 -v 保存数据 |
| 测试环境 | 可选择性挂载 |
| 生产环境 | 统一放在挂载卷或 NFS 存储上 |
| 容器迁移 | 拷贝宿主机对应路径即可恢复数据 |
十、总结一句话
没有 -v,容器删了数据也没了;
有了 -v,数据存在宿主机目录中,删容器也不影响。
只要新容器挂载相同目录,数据就能“原地复活”。
延伸阅读
Docker 官方文档:https://docs.docker.com/storage/volumes/
推荐命令:
docker volume ls # 查看所有数据卷 docker volume inspect 卷名 docker system df # 查看磁盘空间占用
到此这篇关于Docker数据持久化之如何让新容器同步旧数据详解的文章就介绍到这了,更多相关Docker新容器同步旧数据内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
