Skip to content

备份

Kestrel 把所有重要数据都存在一个目录树里。备份就一条命令。

打快照

bash
kestrel backup /var/backups/kestrel-$(date +%F).tar.gz

或者在 Docker 容器里:

bash
docker exec kestrel /kestrel backup /data/snapshot.tar.gz
docker cp kestrel:/data/snapshot.tar.gz ./

kestrel backup 内部做的事:

  1. 用 SQLite VACUUM INTO 写一份临时文件。这是事务性快照 —— 备份过程中服务端继续接收写入,生成的 DB 文件完全自包含(不需要 WAL 边车文件)。
  2. 遍历 sourcemap 目录树,把每个 .map 文件追加进归档。
  3. 输出一个 .tar.gz:根目录是 kestrel.db,每个 sourcemap 在 sourcemaps/<project>/<release>/<file>.map

恢复

恢复就是 tar 解压 + 路径替换:

bash
# 1. 停掉运行中的服务(避免和 data 目录抢访问)
docker stop kestrel

# 2. 把归档解压到 data volume
docker run --rm -v kestrel-data:/data -v $PWD:/in alpine \
  sh -c 'tar -xzf /in/snapshot.tar.gz -C /data'

# 3. 启服务
docker start kestrel

DB、sourcemap、管理员密码文件、session 密钥都在 /data 下,恢复出来的容器和源容器表现完全一致。项目 token 也不会变 —— 它们的 hash 跟着归档过来了。

定时执行

kestrel backup 适合放进 cron / systemd timer / Kubernetes CronJob —— 没有 API 要调,就是一条 CLI。归档的清理交给你已经在用的工具(tmpwatchlogrotate、S3 lifecycle)。

包含在备份里的

  • 自动生成的 .admin_password 文件。如果失去访问,启动时设置 KESTREL_ADMIN_PASSWORD=... 即可(环境变量优先级高于文件),或者把文件删掉让下次启动重新生成。
  • KESTREL_DATA 下 DB 和 sourcemap 之外的任何东西。如果你有自定义集成往那里写文件,要单独备份。

验证一份快照

归档里的 kestrel.db 是一个普通 SQLite 文件。不恢复直接看:

bash
tar -xzf snapshot.tar.gz kestrel.db
sqlite3 kestrel.db 'SELECT COUNT(*) FROM events; SELECT COUNT(*) FROM issues;'

数字看着对,备份就没问题。

基于 MIT 协议发布。