Docker数据卷持久化,容器数据持久存储方案

容器删除后数据跟着消失,是新手用Docker部署数据库或网站时最常踩的坑。
Docker数据卷持久化就是解决这个问题的标准方案:把容器内需要保留的目录映射到宿主机磁盘,容器重建后数据依然存在。
下面按准备、操作、避坑、验证的顺序,用MySQL容器做完整演示,零基础也能照着执行。

先理解两种持久化方式

Docker官方推荐的数据持久化方式主要有两种:绑定挂载(bind mount)和命名卷(named volume)。

  • 绑定挂载:把宿主机上你指定的目录,例如 /data/mysql,挂载到容器内的数据目录。路径完全由你控制,适合需要直接查看、备份或迁移数据的场景。
  • 命名卷:由Docker管理,存储在 /var/lib/docker/volumes/ 下,你只需要给卷起个名字。适合不想关心宿主机路径、追求跨平台一致性的场景。

判断标准:需要直接操作宿主机文件就选绑定挂载,追求开箱即用就选命名卷。 两者都能实现容器数据持久存储,不存在谁绝对更好。

动手前的环境和检查项

开始前确认三件事:

  1. 已安装Docker,执行 docker version 能看到Client和Server信息。
  2. 宿主机有足够磁盘空间,用 df -h 查看目标分区剩余容量。
  3. 明确要持久化的容器内路径。以MySQL 8为例,数据目录通常是 /var/lib/mysql,配置文件在 /etc/mysql/conf.d。

如果不确定容器内路径,可以先启动一个临时容器进去看:

docker run -it --rm mysql:8 bash
# 进入后执行 ls /var/lib/mysql 确认目录

用绑定挂载部署一个可持久化的MySQL

下面这套命令是本文核心,建议逐行执行。

创建宿主机目录:

mkdir -p /data/mysql/data /data/mysql/conf

启动容器,把两个目录分别挂载进去:

docker run -d \
  --name mysql-persist \
  -p 3306:3306 \
  -e MYSQL_ROOT_PASSWORD=YourStrongPass123 \
  -v /data/mysql/data:/var/lib/mysql \
  -v /data/mysql/conf:/etc/mysql/conf.d \
  mysql:8

关键参数说明:

  • -v /data/mysql/data:/var/lib/mysql:冒号左边是宿主机路径,右边是容器内路径,顺序不能反。
  • -e MYSQL_ROOT_PASSWORD:首次启动会初始化数据库,这个密码只在数据目录为空时生效。
  • --name mysql-persist:固定容器名,方便后续操作。

执行后确认容器状态:

docker ps --filter name=mysql-persist

看到状态为 Up 即启动成功。

验证数据是否真正持久化

光看容器运行不够,要实际验证数据能留存。

第一步,进入容器创建测试数据:

docker exec -it mysql-persist mysql -uroot -p

输入密码后执行:

CREATE DATABASE persist_test;
USE persist_test;
CREATE TABLE t1(id INT PRIMARY KEY, note VARCHAR(50));
INSERT INTO t1 VALUES (1, 'hello-volume');
EXIT;

第二步,删除容器再重建,模拟真实故障场景:

docker rm -f mysql-persist
docker run -d --name mysql-persist -p 3306:3306 \
  -e MYSQL_ROOT_PASSWORD=YourStrongPass123 \
  -v /data/mysql/data:/var/lib/mysql \
  mysql:8

第三步,重新查询数据:

docker exec -it mysql-persist mysql -uroot -p -e "SELECT * FROM persist_test.t1;"

如果还能查到 hello-volume 这条记录,说明Docker数据卷持久化已经生效。容器可以随时删除重建,数据保存在宿主机目录里。

容易踩坑的几个地方

权限问题导致容器起不来。 MySQL容器内进程以mysql用户运行,如果宿主机目录权限过严,会报 Permission denied。
可先临时放宽:

chown -R 999:999 /data/mysql/data

999是MySQL镜像内mysql用户的常见UID,具体以镜像实际配置为准。

挂载路径写反。 宿主机路径在前、容器路径在后。
写反可能把宿主机目录覆盖成空目录,甚至影响系统文件。

初始化密码不生效。 如果宿主机目录里已有旧数据,MYSQL_ROOT_PASSWORD 不会重新设置。
要重置只能清空数据目录,操作前务必备份。

直接删容器不等于删数据。 docker rm 只删除容器层,绑定挂载的宿主机目录和命名卷默认会保留。
清理命名卷要用 docker volume rm,且确认不再需要。

备份与迁移建议

持久化之后,备份逻辑就简单了。
绑定挂载场景下,直接打包宿主机目录即可:

tar -czf /backup/mysql-$(date +%F).tar.gz /data/mysql/data

迁移到另一台服务器时,把压缩包传过去解压到相同路径,再用同样的 -v 参数启动容器,数据即可接续使用。
命名卷场景可以用 docker run --rm -v 卷名:/from -v $(pwd):/to alpine tar czf /to/backup.tar.gz -C /from . 导出。

无论用哪种方式,都建议定期做一次“删除容器再重建”的演练。能通过重建验证的数据持久化方案,才算真正可靠。

常见疑问

命名卷和绑定挂载到底选哪个?
需要自己用工具直接读写数据文件、做异地备份,选绑定挂载;
只想让容器数据不丢、不关心文件放哪,选命名卷。
生产环境两者都常见,关键是团队要统一约定,避免同一服务混用两种方式。

容器删除后数据还在,但为什么新容器读不到?
先检查 -v 参数是否和原来完全一致,路径大小写、末尾斜杠都可能有影响。
其次确认宿主机目录没有被其他程序改动权限或清空。

数据卷会占用大量磁盘吗?
会。
镜像层和卷数据分开计算,docker system df 可以查看卷占用。
长期运行建议监控宿主机磁盘,并定期清理无用卷。

分享到:
上一篇
无头CMS多端同步,网站小程序APP内容统一更新
下一篇
UPS容量计算,服务器断电续航时间测算:UPS容量计算
1
系统公告

泽御云中秋国庆双节活动上线:新购8折,拼团3.99元起

尊敬的用户:
泽御云“月满中秋·礼贺国庆”双节活动现已开启,活动时间为2026年9月23日至10月10日。 活动期间可享以下福利:
1. 常规云服务器新购使用优惠码“泽御中秋国庆同乐”,符合条件的订单享8折优惠。
2. 香港精品云服务器5人拼团低至3.99元,部分4核4G套餐3人拼团年付388元,续费同价。
3. 新用户购买年付云服务器,符合活动规则可赠送2个月使用时长。
4. 老用户续费季度赠15天,续费年度赠2个月;活动期间升级配置免收配置迁移手续费。
5. 推荐好友成功下单,符合条件的推荐人可获赠7天服务器使用时长。
6. 活动期间享宕机补偿标准翻倍、简单网站迁移协助及技术工单优先处理权益。
温馨提示:优惠码不适用于拼团套餐、活动轻量产品、年付订单及续费订单;拼团套餐为独立特价活动,不与赠时类福利叠加。赠送时长不可折现、退款或跨账户转移,具体规则以活动页面说明为准。
服务中心
客服
在线客服
24小时为您服务
咨询
联系我们
联系我们,为您的业务提供专属服务。
24/7 技术支持
如果您遇到寻求进一步的帮助,请过工单与我们进行联系。
24/7 即时支持
泽御云
售前客服
泽御云
泽御云
售后客服
泽御云
技术支持
评价
您对当前页面的整体感受是否满意?
😞
非常不满意
😕
不满意
😐
一般
🙂
满意
😊
非常满意