备份
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 内部做的事:
- 用 SQLite
VACUUM INTO写一份临时文件。这是事务性快照 —— 备份过程中服务端继续接收写入,生成的 DB 文件完全自包含(不需要 WAL 边车文件)。 - 遍历 sourcemap 目录树,把每个
.map文件追加进归档。 - 输出一个
.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 kestrelDB、sourcemap、管理员密码文件、session 密钥都在 /data 下,恢复出来的容器和源容器表现完全一致。项目 token 也不会变 —— 它们的 hash 跟着归档过来了。
定时执行
kestrel backup 适合放进 cron / systemd timer / Kubernetes CronJob —— 没有 API 要调,就是一条 CLI。归档的清理交给你已经在用的工具(tmpwatch、logrotate、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;'数字看着对,备份就没问题。