Search K
从 1.x 升级到 2.0
SnapOtter 1.x 将所有内容存储在单个 SQLite 文件中,并以单容器方式运行。SnapOtter 2.0 使用 PostgreSQL 和 Redis。本指南将带你把 1.x 安装迁移到 2.0 而不丢失数据。
简要版:复用你现有的 /data 卷,2.0 会在首次启动时自动导入你的 1.x 数据库。你的用户、已保存的文件、设置、API 密钥和流水线都会一并迁移过来。旧数据库从不会被修改,因此你随时可以回滚。
致我们的 1.x 用户
你们中的许多人从第一天起就信任 SnapOtter,你们的反馈塑造了这个版本。2.0 在底层做了大量改动,本指南的存在就是为了让这次迁移不会让你损失任何在意的东西。你的账户、文件、设置、API 密钥和流水线都会平移过来,你的旧数据库从不会被触碰。感谢你与我们一同升级。
开始之前:备份整个 /data 卷
每次都先做这一步。备份整个 /data 卷,而不仅仅是 snapotter.db 文件。
原因如下。1.x 以 WAL 模式运行 SQLite,因此一个已停止的 1.x 容器通常会把大部分已提交的数据留在 snapotter.db-wal 中,旁边只有一个几乎为空的 snapotter.db。仅复制 snapotter.db 会抓到一个空数据库,并悄无声息地丢失所有内容。该卷同时携带 snapotter.db、snapotter.db-wal、snapotter.db-shm 以及你的 files/ 目录,它们必须作为一个整体一起迁移。
bash
# Adjust the volume name to match yours (see "Check your volume name" below).
docker run --rm -v SnapOtter-data:/data -v "$PWD":/backup \
alpine tar czf /backup/snapotter-1x-data.tgz -C /data .先升级到 1.17.2
在迁移到 2.0 之前,先把你的 1.x 安装升级到最新的 1.x 版本(1.17.2)。这能让 1.x 运行它自己的最终 schema 迁移,从而让 2.0 从一个已知且完整的 schema 导入。不支持从更旧的 1.x 直接升级到 2.0。
检查你的卷名
只有当 2.0 栈挂载的卷与你的 1.x 安装使用的卷相同时,导入器才能看到你的数据。Docker 卷名区分大小写,较旧的 README 片段用的是小写的 snapotter-data,而 Compose 文件用的是 SnapOtter-data。确认你用的是哪一个:
bash
docker volume ls | grep -i snapotter在你的 2.0 配置中使用那个确切的名称。
路径 A:单容器(最快)
如果你用单个 docker run 运行 SnapOtter,那就继续这么做。当你不设置 DATABASE_URL 或 REDIS_URL 时,2.0 会在容器内启动一个内嵌的 PostgreSQL 和 Redis,并在首次启动时自动检测并导入 /data/snapotter.db。
bash
docker run -d --name snapotter -p 1349:1349 \
-v SnapOtter-data:/data \
snapotter/snapotter:latest留意日志中类似这样的一行:
Imported 1.x SQLite database: {"tables":{"users":2,"teams":1,...},"blobs":{"present":1,"missing":0}}就这样。用你现有的凭据登录即可。
路径 B:Compose(生产环境推荐)
2.0 Compose 栈运行三个服务(应用、Postgres、Redis)。为应用服务复用你的 1.x /data 卷。应用会自动检测 /data/snapotter.db 并在首次启动时将其导入 Postgres。
yaml
services:
SnapOtter:
image: snapotter/snapotter:latest
volumes:
- SnapOtter-data:/data # your existing 1.x volume
- SnapOtter-workspace:/tmp/workspace
environment:
- DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter
- REDIS_URL=redis://:snapotter@redis:6379
# ...如果你更想显式指向旧数据库,设置 SQLITE_MIGRATE_PATH=/data/snapotter.db。显式路径始终优先于自动检测。
先预览导入(可选)
若想在不写入任何内容的情况下准确查看将会导入什么,可针对你的数据库文件运行一次 dry run:
bash
pnpm --filter @snapotter/api migrate:sqlite -- /path/to/snapotter.db --dry-run它会打印每个表的行数、在磁盘上找到的已保存库文件数量,以及任何将被规范化的任务状态。它无需运行中的 Postgres。
哪些会迁移,哪些不会
会迁移的:
- 用户,以及登录能力。密码哈希保持不变,因此相同的用户名和密码仍然有效。
- 团队、设置(包括你的实例标识)、角色、API 密钥(它们继续有效)以及已保存的流水线。
- 任务历史记录。
- 你已保存的文件库,包括记录和实际文件,因为
/data/files在卷上得到保留。
不会迁移的:
- 登录会话。升级后每个人都需要重新登录一次。凭据保持不变,因此这只是一次性重新登录,仅此而已。
- 旧处理任务的输入和输出文件。它们存放在临时工作区中,按设计已被清除。任务历史记录仍然保留。
- 来自 1.x 的每用户分析同意标记,它在 2.0 中没有对应项(2.0 的分析是实例级设置)。
关闭导入
如果即便卷上存在 snapotter.db,你也刻意想要一个全新的数据库,请设置 SQLITE_MIGRATE_PATH=off。
如果 2.0 实例中已有数据
导入器只会在空数据库上运行。如果你全新启动了 2.0(创建了数据),随后又挂载了一个旧的 snapotter.db,2.0 会检测到它但不会导入,因为合并两个数据集可能会在 ID 上冲突。你会在日志中看到一条警告。要导入 1.x 数据,你需要一个空实例:
- 如果 2.0 实例只包含默认管理员(你其实还没真正使用过它),停止栈,移除 Postgres 卷(
SnapOtter-pgdata),然后在旧的/data存在的情况下再次启动。它会干净地导入。这只会抹掉一次性的 Postgres 数据,而不是你的 1.x 数据库。 - 如果 2.0 实例包含你想保留的真实数据,那这两个数据集无法自动合并。请导出你需要的内容,并将 1.x 数据导入到一个独立的全新部署中。
回滚
升级从不会修改或删除你的 1.x snapotter.db。如果你需要回退到 1.x,针对同一个卷重新部署 1.x 镜像即可。升级后你在 2.0 中创建的任何内容都存在于 Postgres 中,不会出现在 1.x 数据库里,所以如果打算回滚,请尽早进行。
