在法国用二手 NAS 跑 Gitea,备份别只依赖 Hyper Backup
去年从 Leboncoin 上收了台 DS218,两块 4T 盘做 SHR,DSM 7.2。上面跑了个 Docker 版 Gitea,仓库加起来大概 12G,镜像走了我另一台小机器上的 registry 缓存,所以 NAS 上只留了数据卷。问题出在备份:我一开始只挂了 Synology 的 Hyper Backup,每天推到一块接在 USB 口的外置盘上,觉得够了。
真正的做法是把两件事拆开。数据库用 Gitea 自带的 dump,仓库目录用 rsync 落到另一块盘,Hyper Backup 只负责把 dump 文件再抄一份到外置盘。
# 在 NAS 上的 docker 容器里执行,输出到 bind mount 的 /backup
docker exec -u git gitea \
/usr/local/bin/gitea dump -c /data/gitea/conf/app.ini \
-f /backup/gitea-dump-$(date +%F).zip
仓库的裸目录我另外同步一次,因为 dump 里虽然包含仓库,但恢复时整包解压对 12G 的数据量并不轻松:
rsync -a --delete /volume1/docker/gitea/git/repositories/ \
/volume2/backup/gitea-repos/
为什么这样做:Hyper Backup 备份的是文件系统上的块和文件,它不理解 Gitea 的 SQLite 库正在被写入。直接抄 .db 文件,赶上有写入时可能拿到一个不一致的副本,恢复出来就是打不开。dump 走的是 Gitea 自己的导出路径,一致性有保证,代价是需要停写或者接受 dump 期间的部分不一致,所以我把 dump 放在凌晨,并且先跑 dump 再 rsync 仓库目录。
失效的地方我也踩过:gitea dump 默认会把整个 data 目录打进去,包括仓库和附件,12G 的数据卷生成接近 10G 的 zip,NAS 的 CPU 是 ARM,跑一次要二十多分钟,期间 Gitea 响应明显变慢。后来我加了 --skip-repository,仓库单独靠 rsync,dump 缩到几百兆,时间降到两三分钟。另一个坑是 USB 外置盘在 DSM 休眠后会掉,Hyper Backup 任务失败但不一定发通知,我有一次隔了六天才发现外置盘根本没挂上。现在加了一个 cron,每天检查挂载点是否存在,不存在就写一行到日志,我再从别的地方看。
还有一个边界:rsync 的 --delete 在源目录被误挂成空目录时会把备份清空,所以我在脚本开头加了一句判断,源目录里 find -maxdepth 1 -type d | wc -l 小于某个数就直接退出。这个阈值是我自己拍的,不保证通用。
你们在这种 ARM 小 NAS 上备份 Gitea,是接受 dump 慢一点换一致性,还是干脆把仓库放到另一台 x86 机器上、NAS 只当冷备?
0 条评论
还没有评论,写下第一条。