Busabase

备份与恢复

必须备份的三样东西、一个把三样都做了的脚本,以及一次你应该在真正需要之前就跑一遍的恢复演练。

一个 Busabase 实例在磁盘上是三样东西,漏掉任何一样的备份都不叫备份。

里面是什么丢了会怎样
数据库全部结构化内容:空间、记录、文档、成员、权限、历史全没了
对象存储附件——文件的实际字节记录都在,但每个附件链接都是坏的
配置.envseaweed-s3.json你打不开自己还留着的那个数据库

第三样最容易被忽略。.env 里有 Postgres 密码和会话签名密钥,存储配置里有 S3 凭据。只恢复了数据而没有它们,你面对的就是一堆解不开的东西。

备份

Compose 包里带了 backup.sh,三样一起做:

./backup.sh /var/backups/busabase

它会写出一个带时间戳的目录,包含 database.sql.gzstorage.tar.gz 和配置文件副本。预期用法是配一条每日 cron:

0 3 * * * /opt/busabase-selfhosted/backup.sh /var/backups/busabase

备份里含有你的数据库密码和会话密钥。请用和生产完全同级的标准对待备份目录——脚本会把输出设成 600,别去放松它。

一体机怎么备

所有东西都在一个卷里,那就备这个卷:

docker run --rm -v busabase-data:/data:ro -v "$PWD":/out \
  alpine tar czf /out/busabase-data.tar.gz -C /data .

这里面包含 /data/.credentials,也就是那套生成密钥的唯一副本。

恢复

恢复到一套部署,而不是覆盖正在跑的那套。万一这份备份是坏的,你手上还留着原件。

# 1. 起一套全新部署,然后先停掉 app,避免恢复过程中有写入
docker compose up -d postgres seaweedfs
docker compose stop app

# 2. 数据库
gunzip -c database.sql.gz | docker compose exec -T postgres psql -U busabase -d busabase

# 3. 对象存储
docker run --rm -v busabase-premium_seaweedfs_data:/data -v "$PWD":/in \
  alpine tar xzf /in/storage.tar.gz -C /data

# 4. 配置,然后启动
cp .env seaweed-s3.json /opt/busabase-selfhosted/
docker compose up -d

如果恢复出来的实例访问地址与原来不同——换了主机,或者只是换了端口——启动前务必把恢复出来的 .env 里的 APP_URL 改成新地址。登录 cookie 是按它签发的,沿用旧值的表现是:登录看起来成功,然后立刻弹回登录页,日志里什么都不说。这次为发版做恢复演练时就踩了这个坑。

在需要它之前先演练一次

一份从没恢复过的备份只是一个假设。找台闲置机器跑一遍,之后检查三件事:

  1. 能登录 —— 证明 BETTER_AUTH_SECRET 带过来了。
  2. 记录条数和原库一致 —— 证明数据库完整恢复。
  3. 打开一个附件 —— 证明对象存储和它的凭据两样都带过来了。

第三点才是真正会挂的那一点。它也恰恰是「随便看一眼觉得没问题」完全发现不了的,因为在有人点开某个文件之前,每一页都渲染得好好的。

On this page