NAS 上跑了 20 个 Docker 容器?这套备份方案让你睡得安稳
很多人把 NAS 当服务器用,Docker 里跑着十几二十个容器:照片管理、下载工具、智能家居、个人博客……直到某天硬盘挂了、误操作删了容器、或者系统升级翻车,才发现容器配置和数据全没了。重建一个容器可能要半小时,重建 20 个就是一整天,更别提那些调了半年才稳定的配置参数。
这篇文章分享我在威联通/群晖 NAS 上实践的 Docker 容器备份方案,核心目标是:配置能秒恢复,数据不丢失,操作够简单。
为什么容器备份容易被忽视?
很多人以为「NAS 有 RAID 就够了」,但 RAID 只防硬盘物理损坏,防不了这些:
误删容器:在 Container Station 或 Portainer 里手滑点了删除
配置丢失:重装系统、升级 NAS 固件后容器配置全清空
数据污染:容器内程序 bug 导致数据库损坏,RAID 会忠实地把坏数据同步到所有盘
勒索病毒:加密你的共享文件夹,包括容器挂载的数据目录
容器的「配置」和「数据」需要分开备份,前者决定容器能不能起来,后者决定你的内容还在不在。
方案总览:三层防护
我的方案分三层,覆盖不同场景:

下面分别说怎么做。
第一层:用 docker-compose 管理所有容器
为什么不用图形界面创建容器?
Container Station 或 Portainer 的图形界面很直观,但有个致命问题:配置全在数据库里,导出很麻烦,恢复更麻烦。用 docker-compose.yml 的好处是:
一个文本文件定义所有配置:镜像版本、端口、挂载路径、环境变量全在里面
版本控制友好:可以用 Git 管理,改了什么一目了然
秒级恢复:只要文件在,一条命令就能重建所有容器
实操步骤
1. 创建统一的 compose 文件
在 NAS 共享文件夹里建个目录,比如 /share/Container/docker-compose/,创建 docker-compose.yml:
version: '3.8'
services:
# 照片管理 - PhotoPrism
photoprism:
image: photoprism/photoprism:latest
container_name: photoprism
restart: unless-stopped
ports:
- "2342:2342"
environment:
PHOTOPRISM_ADMIN_PASSWORD: "你的密码"
PHOTOPRISM_DATABASE_DRIVER: "mysql"
PHOTOPRISM_DATABASE_SERVER: "mariadb:3306"
volumes:
- /share/Photos:/photoprism/originals
- /share/Container/photoprism/storage:/photoprism/storage
depends_on:
- mariadb
# 数据库 - MariaDB
mariadb:
image: mariadb:10.11
container_name: mariadb
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: "你的密码"
MYSQL_DATABASE: "photoprism"
volumes:
- /share/Container/mariadb:/var/lib/mysql
# 下载工具 - qBittorrent
qbittorrent:
image: linuxserver/qbittorrent:latest
container_name: qbittorrent
restart: unless-stopped
ports:
- "8080:8080"
- "6881:6881"
environment:
PUID: 1000
PGID: 1000
TZ: Asia/Shanghai
volumes:
- /share/Container/qbittorrent/config:/config
- /share/Downloads:/downloads
# 更多容器...
2. 启动容器
SSH 登录 NAS,进入目录:
cd /share/Container/docker-compose
docker-compose up -d
所有容器就起来了。以后要改配置,直接编辑 yml 文件,再执行:
docker-compose up -d --force-recreate
3. 备份 compose 文件
方法一:定期复制到 U 盘
每次改完配置,手动复制 docker-compose.yml 到 U 盘或移动硬盘。
方法二:自动同步到云盘
用 NAS 自带的「Cloud Drive Sync」或第三方工具,把 compose 文件夹同步到坚果云/OneDrive。
方法三:Git 版本控制(推荐)
在 NAS 上装 Git,初始化仓库:
cd /share/Container/docker-compose
git init
git add docker-compose.yml
git commit -m "初始配置"
每次修改后提交:
git add .
git commit -m "增加 Jellyfin 容器"
再推送到 GitHub 私有仓库(记得加 .gitignore 排除密码文件)。
第二层:数据卷定期快照
容器配置能秒恢复,但容器内的数据(数据库、用户上传的文件、程序配置)需要单独备份。
核心原则:数据和配置分离
所有容器的数据都挂载到 NAS 共享文件夹,不要放在容器内部。比如:
❌ 错误做法:数据库文件在容器内的 /var/lib/mysql,没挂载出来
✅ 正确做法:挂载到 /share/Container/mariadb:/var/lib/mysql
这样数据在 NAS 上,可以用 NAS 自带的快照功能保护。
威联通快照设置
Storage & Snapshots → 选择存储池 → 快照
创建快照计划:
保护目录:
/share/Container(所有容器数据)频率:每天凌晨 3 点(容器访问量低的时候)
保留策略:最近 7 天每天一份,最近 4 周每周一份
恢复数据:
右键文件夹 → 从快照还原
选择时间点,秒级恢复
群晖快照设置
Snapshot Replication → 快照
选择共享文件夹
Container,启用快照:计划:每天 03:00
保留:7 天内每天,4 周内每周
恢复:在 File Station 里右键文件夹 → 还原以前的版本
针对数据库的特殊处理
快照是文件系统级别的,对于正在运行的数据库,直接快照可能抓到不一致的状态。建议在快照前先导出:
创建定时脚本 /share/Container/backup_db.sh:
#!/bin/bash
# 导出 MariaDB
docker exec mariadb mysqldump -uroot -p你的密码 --all-databases > /share/Container/backup/mariadb_$(date +%Y%m%d).sql
# 导出 PostgreSQL (如果有)
docker exec postgres pg_dumpall -U postgres > /share/Container/backup/postgres_$(date +%Y%m%d).sql
# 只保留最近 7 天的备份
find /share/Container/backup -name "*.sql" -mtime +7 -delete
在 NAS 计划任务里设置每天凌晨 2:50 执行(比快照早 10 分钟)。
第三层:异地冷备份
前两层都在 NAS 本地,如果遇到:
硬件彻底损坏(主板烧了、被雷劈了)
勒索病毒(加密了所有文件包括快照)
物理灾害(火灾、水淹)
本地备份就全没用了。需要异地备份。
方案一:定期备份到移动硬盘,存放异地
准备一块移动硬盘,格式化为 ext4(Linux 文件系统,支持权限)
插到 NAS,挂载到
/share/External/Backup创建备份脚本
/share/Container/backup_to_external.sh:
#!/bin/bash
BACKUP_DIR="/share/External/Backup/docker_backup_$(date +%Y%m%d)"
# 创建备份目录
mkdir -p $BACKUP_DIR
# 复制 compose 文件
cp -r /share/Container/docker-compose $BACKUP_DIR/
# 打包所有容器数据(排除缓存目录)
tar -czf $BACKUP_DIR/container_data.tar.gz
--exclude='*/cache'
--exclude='*/tmp'
/share/Container/
# 导出数据库
docker exec mariadb mysqldump -uroot -p你的密码 --all-databases > $BACKUP_DIR/mariadb.sql
echo "备份完成: $BACKUP_DIR"
每周日执行一次,备份完拔下硬盘,放到家里以外的地方(公司、父母家)
方案二:加密上传到云存储
如果数据量不大(<100GB),可以加密后上传到云盘:
#!/bin/bash
# 打包容器数据
tar -czf /tmp/docker_backup.tar.gz /share/Container/docker-compose /share/Container/mariadb /share/Container/photoprism
# 用 GPG 加密(需要先生成密钥对)
gpg --encrypt --recipient 你的邮箱 /tmp/docker_backup.tar.gz
# 上传到云盘(用 rclone 或 NAS 自带同步工具)
rclone copy /tmp/docker_backup.tar.gz.gpg remote:NAS_Backup/
# 清理临时文件
rm /tmp/docker_backup.tar.gz*
每月执行一次即可。
实战演练:模拟灾难恢复
假设你的 NAS 系统崩溃,需要从零恢复所有容器:
场景一:误删容器(配置还在)
SSH 登录 NAS
进入 compose 目录:
cd /share/Container/docker-compose重建容器:
docker-compose up -d耗时:1 分钟
场景二:数据损坏(昨天还是好的)
停止相关容器:
docker-compose stop mariadb在 NAS 管理界面,从快照恢复
/share/Container/mariadb到昨天的版本重启容器:
docker-compose start mariadb耗时:5 分钟
场景三:系统重装(本地数据都在)
重装 NAS 系统,重新启用 Container Station
SSH 登录,安装 docker-compose:
# 威联通 curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose进入目录,启动:
cd /share/Container/docker-compose && docker-compose up -d耗时:10 分钟
场景四:硬件全毁(只有异地备份)
买新 NAS,初始化系统
从移动硬盘或云盘下载备份
解压数据到
/share/Container/恢复数据库:
docker exec -i mariadb mysql -uroot -p你的密码 < mariadb.sql启动容器:
docker-compose up -d耗时:1-3 小时(取决于数据量)
额外建议
1. 记录关键信息
在 compose 文件同目录创建 README.md,记录:
每个容器的用途和访问地址
管理员账号(密码另外存)
特殊配置说明(比如某个容器需要特定内核参数)
灾难恢复时能少走很多弯路。
2. 定期测试恢复流程
备份不测试 = 没备份。每季度找个空闲时间:
在另一台机器(虚拟机也行)上,用备份文件尝试恢复一个容器
检查数据是否完整、功能是否正常
记录遇到的问题,改进备份脚本
3. 监控备份任务
用 NAS 自带的通知功能,在备份脚本里加:
# 备份成功后发通知
curl -X POST https://你的通知服务/api
-d "title=NAS备份成功"
-d "message=Docker容器已备份到移动硬盘"
如果某天没收到通知,说明备份失败了,要及时检查。
总结
容器备份的核心是分层防护:
配置用 docker-compose:秒级恢复,版本可控
数据用快照:防误操作,防数据损坏
异地备份兜底:防硬件损坏,防勒索病毒
这套方案在我的威联通上跑了一年多,经历过两次误删容器、一次数据库崩溃,都在 10 分钟内恢复了。花一个周末搭好备份体系,能省掉无数个通宵重建容器的夜晚。
如果你的 NAS 上跑着重要服务,强烈建议现在就开始做备份。有问题欢迎评论区交流。
作者声明本文无利益相关,欢迎值友理性交流,和谐讨论~
