必须备份业务数据卷、自定义镜像和配置元数据;宿主机挂载卷直接tar压缩,docker volume需用临时容器只读导出;数据库优先逻辑备份(mysqldump),redis用save触发rdb快照;恢复须按环境→数据→验证顺序执行。
容器数据一旦丢失,往往比代码出错更难挽回。真正可靠的备份不是“有就行”,而是能精准还原、不丢事务、不破一致性。核心不在工具多炫,而在搞清三件事:哪些必须备份、什么时候备份最安全、恢复时怎么避免二次踩坑。
必须备份的三类东西,漏一项就可能全盘翻车
很多人只打包镜像或只导SQL,结果迁移后服务起不来。完整备份必须覆盖:
-
业务数据卷:MySQL 的
/var/lib/mysql、Redis 的/data、Nginx 日志目录等——这些是挂载在容器外的真实路径,删容器不删它,但宿主机崩了或误删目录就真没了; - 自定义镜像:你 build 出来的前端 Vue 镜像、SpringBoot 后端镜像——别指望重新 build 就能一模一样,环境变量、构建缓存、依赖版本都可能漂移;
-
配置与元数据:docker-compose.yml、.env 文件、Nginx 配置、MySQL my.cnf、甚至 volume 创建命令(如
docker volume create mysql_data)——没有它们,你连挂载点都对不上。
数据卷备份:分清宿主机挂载 vs Docker 管理卷
两种常见挂载方式,备份逻辑完全不同:
-
宿主机目录挂载(如
-v ./mysql/data:/var/lib/mysql):直接压缩整个./mysql/data目录即可。用tar -zcf mysql-data-$(date +%Y%m%d).tar.gz ./mysql/data,简单、快、可读性强; -
Docker 管理的 volume(如
-v mysql_data:/var/lib/mysql):不能直接访问宿主机路径(位置由 Docker 内部管理),得靠临时容器中转:docker run --rm -v mysql_data:/source:ro -v $(pwd):/backup alpine tar -zcf /backup/mysql_volume_$(date +%Y%m%d).tar.gz -C /source .
关键是加:ro只读挂载,避免备份时写入冲突。
数据库备份不能只靠目录打包,必须分层做
MySQL 或 PostgreSQL 这类有状态服务,仅拷贝数据文件(物理备份)风险极高:
-
逻辑备份(推荐日常用):用
mysqldump导出 SQL,兼容性好、可选表恢复、支持跨版本。命令示例:docker exec mysql-container mysqldump -u root -p'123456' spring_db > backup_$(date +%Y%m%d).sql; -
物理备份(大库/紧急快照):需先停库保证一致性(
docker stop mysql-container),再docker cp或tar整个数据目录,恢复时必须用同版本 MySQL,且不能跳过初始化步骤; -
Redis 特别注意:RDB 是默认持久化方式,
docker exec redis redis-cli -a 'pwd' save触发一次快照,生成dump.rdb。恢复只需替换该文件并重启容器——但别忘了检查redis.conf中dbfilename和dir是否匹配。
恢复不是“复制粘贴”,关键在顺序和验证
恢复失败,八成是因为步骤乱了或没验证:
- 先恢复基础环境:重建 volume(
docker volume create xxx)、拉取镜像(docker pull或docker load -i)、校验 compose 文件语法(docker compose config); - 再恢复数据:MySQL 先建空库,再用
cat backup.sql | docker exec -i mysql mysql -u root -p'xxx' spring_db导入;Redis 替换dump.rdb后务必docker compose restart redis,不能只start; - 最后必须验证:进容器查
SELECT COUNT(*) FROM user;、看日志有没有报错、用应用真实访问一次接口——截图留证,才算完成。











