Docker 容器数据备份,如何定期自动备份?
前言:为什么要自己做定期备份?
很多新手以为Docker容器跑起来就万事大吉,但容器本身是短暂的,一旦容器被误删、磁盘故障或配置出错,里边的数据可能瞬间丢失。
虽然有些云平台提供快照,但自己掌握一套Docker容器数据备份方案,才能做到定期自动备份心中有数。
本文会教你用最通用的cron + Shell脚本方式,实现按天或按小时自动备份容器数据卷。
所有步骤都在命令行完成,无需安装额外工具,适合CentOS 7+、Ubuntu 20.04+以及安装了宝塔面板的服务器(宝塔同样支持终端操作)。
第一步:确认容器数据存在哪
备份前先搞清楚数据在宿主机上的真正位置。
Docker数据主要有两种存放形式:
- 绑定挂载(bind mount):创建容器时用
-v /宿主机路径:/容器内路径指定的目录。 - 命名数据卷(named volume):通过
docker volume create创建,或用-v 卷名:/容器内路径自动生成。
查看容器实际挂载:
docker inspect 容器名 | grep -A 5 "Mounts"
输出中 Source 字段就是宿主机上的真实路径,记下来,备份脚本会用到它。
第二步:编写备份脚本
我们用 tar 加上日期后缀来打包,保留最近7天的备份,超过的自动删除。
新建文件 /opt/docker-backup.sh:
#!/bin/bash
# Docker容器数据备份脚本
# 请根据实际情况修改以下变量
BACKUP_DIR="/backup/docker" # 备份存放目录
SOURCE_DIRS=(
"/var/lib/docker/volumes/myapp_data/_data" # 数据卷真实路径,可多个
"/opt/myapp/config" # bind mount 目录
)
RETENTION_DAYS=7 # 保留天数
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
# 创建备份目录
mkdir -p "$BACKUP_DIR"
# 逐个打包
for dir in "${SOURCE_DIRS[@]}"; do
basename=$(basename "$dir")
tar czf "${BACKUP_DIR}/${basename}-${TIMESTAMP}.tar.gz" -C "$(dirname "$dir")" "$basename"
done
# 删除过期备份
find "$BACKUP_DIR" -name "*.tar.gz" -mtime +$RETENTION_DAYS -delete
echo "[$(date)] 备份完成,共处理 ${#SOURCE_DIRS[@]} 个目录"
给脚本执行权限:chmod +x /opt/docker-backup.sh。
如果容器跑的是数据库(比如MySQL、PostgreSQL),建议先停写操作或用 docker exec 在容器内导出SQL,再备份导出的文件,避免备份文件损坏。
下面会说明。
第三步:添加cron定时任务
cron是Linux自带的定期自动备份调度器。
执行 crontab -e,追加一行(每天凌晨3点执行):
0 3 * * * /opt/docker-backup.sh >> /var/log/docker-backup.log 2>&1
如果想每6小时备份一次:
0 */6 * * * /opt/docker-backup.sh >> /var/log/docker-backup.log 2>&1
保存退出后,用 crontab -l 确认任务已添加。
日志文件会记录每次执行结果,方便排错。
第四步:常见踩坑与高频问题(避坑指南)
Q1:备份数据库容器时,tar直接打包数据文件可能损坏?
对,因为数据库写操作不会暂停,直接打包可能拿到不一致的状态。
正确做法:在备份脚本里先用 docker exec 容器名 mysqldump 或 pg_dump 导出一份SQL,然后打包SQL文件。
示例(MySQL):
docker exec mysql_container mysqldump -u root -p密码 --all-databases > /tmp/mysql-dump.sql
tar czf /backup/docker/mysql-${TIMESTAMP}.tar.gz -C /tmp mysql-dump.sql
Q2:备份文件占满磁盘怎么办?
脚本里已经加了按天删除,但初始备份文件大小不可控。
建议:
- 经常用
df -h检查/backup分区余量。 - 把备份目录单独挂载到大容量磁盘或远程存储(例如通过NFS)。
Q3:如何知道备份是否成功?
邮件通知或微信机器人较复杂,新手先用最简单的:每天看一眼日志文件 tail -20 /var/log/docker-backup.log。
如果出现 tar: 错误 就要排查。
Q4:怎么恢复数据?
先恢复容器,再停用,然后解压备份替换数据卷目录:
# 停容器(如果有)
docker stop myapp
# 解压备份
cd /var/lib/docker/volumes/myapp_data/_data
tar xzf /backup/docker/myapp_data-20250407-030000.tar.gz --strip-components=1
# 启容器
docker start myapp
第五步:效果验证(确保方案可用)
手动跑一次脚本测试:
bash /opt/docker-backup.sh
去备份目录看看文件是否生成:
ls -lh /backup/docker/
然后模拟数据丢失,按照上一步的恢复流程操作,确认应用能正常启动,数据无异常。
只有验证过的备份才算是真正的安全保障。
写在最后
以上就是一套纯命令行的Docker容器数据备份方案,从确认数据卷、编写脚本到 定期自动备份 的cron配置,每一步都经过了生产环境检验。
如果你还不太熟悉Linux,建议先从简单容器(比如一个Nginx静态文件)练手,再应用到核心业务。
遇到异常时优先回头看避坑部分,大部分问题都能在那里找到解法。