Docker 容器的卷管理与备份策略

Docker 的数据存在容器里,容器删了数据就没了。这篇讲讲我的卷管理和备份方案。

数据持久化

Volume(推荐)

Docker 管理的数据卷:

# 创建

docker volume create mydata

查看

docker volume ls

挂载

docker run -v mydata:/data myimage

优点:Docker 管理,备份迁移方便。

Bind Mount

直接映射宿主机目录:

docker run -v /opt/data:/data myimage

优点:数据在宿主机,看得见摸得着。

我的选择:Bind Mount,数据在 /opt/services/ 目录下看得见,备份脚本好写。

我的目录结构

/opt/services/

├── blog/

│ ├── docker-compose.yml

│ ├── halo-data/ # Halo 数据

│ └── mysql-data/ # MySQL 数据

├── ai/

│ └── ollama-data/ # 模型权重

├── media/

│ ├── alist-data/

│ └── navidrome-data/

└── backup/ # 备份目录

每个服务独立目录,数据通过 volume 映射。

备份策略

1. 数据库备份

#!/bin/bash

DATE=$(date +%F)

MySQL 备份

docker exec halo-mysql mysqldump -u root -p密码 halo_db > /opt/services/backup/halo-$DATE.sql

压缩

tar czf /opt/services/backup/halo-$DATE.tar.gz /opt/services/blog/halo-data

删旧备份(保留 7 天)

find /opt/services/backup/ -mtime +7 -delete

2. 定时任务

crontab -e

每天凌晨 3 点备份

0 3 * * * /opt/scripts/backup.sh >> /var/log/backup.log 2>&1

3. 异地备份

备份到云端:

# 用 rclone 同步到阿里云盘/Google Drive

rclone copy /opt/services/backup/ remote:backup/halo/ -v

数据恢复

恢复 MySQL

# 停服务

cd /opt/services/blog

docker compose down

恢复数据库

docker exec -i halo-mysql mysql -u root -p密码 halo_db < backup-2026-04-02.sql

启动

docker compose up -d

恢复文件

tar xzf backup-2026-04-02.tar.gz -C /

踩坑记录

坑 1:volume 找不到

docker volume ls 查看。匿名卷容易丢,建议用命名卷或 bind mount。

坑 2:备份失败

MySQL 容器没启动时 mysqldump 会失败。检查容器状态:

docker ps | grep mysql

坑 3:磁盘满

备份文件太大,磁盘爆了。监控磁盘:

df -h

设好清理策略,超过 7 天自动删。

我的备份清单

| 备份项 | 频率 | 保留时间 | 存储位置 |

|--------|------|----------|----------|

| MySQL | 每天 | 7 天 | 本地 + 云端 |

| 文件 | 每周 | 4 周 | 本地 + 云端 |

| 配置 | 每次改 | 永久 | Git |

总结

Docker 数据管理核心:

- 用 Bind Mount — 数据看得见

- 定时备份 — 每天自动化

- 云端同步 — 本地挂了还能恢复

- 定期测试 — 恢复脚本要试,别等真的挂了才发现不能用