Karakeep 服务器迁移指南:使用官方 CLI 完整迁移数据到新服务器
【免费下载链接】hoarderA self-hostable bookmark-everything app (links, notes and images) with AI-based automatic tagging and full text search项目地址: https://gitcode.com/GitHub_Trending/ho/hoarder
本指南以 Karakeep(原 Hoarder)官方文档中的服务器迁移章节为核心,讲解如何使用官方 CLI 的migrate命令,将用户设置、列表、RSS 源、AI 提示词、Webhook、标签、规则引擎规则以及书签(链接、笔记、图片/PDF 资产)从源服务器完整迁移到目标服务器。读完本文,你将掌握迁移命令的完整参数、内部执行顺序与底层实现原理,并能在换机、换部署环境或服务器升级时安全、可靠地完成数据搬迁。
迁移命令能做什么
migrate命令负责把用户自有数据从源服务器复制到目标服务器,迁移顺序固定,依次为:
- 用户设置(User settings)
- 列表(Lists,保留层级结构与配置)
- RSS 源(RSS feeds)
- AI 提示词(AI prompts,含自定义提示词及其启用状态)
- Webhook(URL 与事件)
- 标签(Tags,确保按名称存在)
- 规则引擎规则(Rule engine rules,ID 重映射为目标服务器的对应 ID)
- 书签(Bookmarks,链接、文本与资产),创建后补挂正确的标签并加入正确的列表
上述顺序与源码中migrate命令的执行步骤完全一致,见 apps/cli/src/commands/migrate.ts:每一步都先打印Migrating xxx …的阶段提示,完成后输出耗时与数量统计,最后以Migration completed successfully结束。
需要注意的迁移边界
- Webhook token 无法通过 API 读取,因此不会被迁移;如目标端需要,必须手动重新填写。
- 资产类书签通过“下载原资产 → 重新上传到目标服务器”的方式迁移,且仅支持图片和 PDF。
- 链接类书签在目标端可能被去重:若目标服务器已存在相同 URL 的书签,则不会重复创建。
前置条件
安装 CLI
两种安装方式任选其一:
NPM 全局安装:
npm install -g @karakeep/cliDocker 运行(不需要本地 Node.js 环境):
docker run --rm ghcr.io/karakeep-app/karakeep-cli:release --help
准备两端凭证
迁移需要同时拿到源服务器与目标服务器的 API Key 和 Base URL:
| 用途 | 参数 |
|---|---|
| 源服务器 | --server-addr、--api-key |
| 目标服务器 | --dest-server、--dest-api-key |
从源码看,CLI 通过 tRPC 客户端访问服务器的/api/trpc端点,并将 API Key 以Bearer形式放入authorization请求头(见 apps/cli/src/lib/trpc.ts)。因此两端服务器都需要开放 API 访问,且提供的 API Key 必须具备读取/创建数据的权限。
另外,--api-key与--server-addr也可以省略,改由环境变量KARAKEEP_API_KEY、KARAKEEP_SERVER_ADDR提供,或写入 CLI 配置文件(默认路径为~/.config/karakeep/config.json,可用XDG_CONFIG_HOME调整),这些解析逻辑见 apps/cli/src/index.ts 与 apps/cli/src/lib/config.ts。未提供任何形式的 API Key 时,CLI 会直接报错退出。
快速开始
在准备好两端凭证后,执行:
karakeep --server-addr https://src.example.com --api-key <SOURCE_API_KEY> migrate \ --dest-server https://dest.example.com \ --dest-api-key <DEST_API_KEY>说明:
- 该命令是长时运行任务,会为每个阶段实时显示进度(在 TTY 终端中进度条会原地刷新,见 apps/cli/src/commands/migrate.ts)。
- 执行前会弹出一个确认提示,询问是否从源地址迁移到目标地址;回答
yes/y继续,其他输入则中止迁移(apps/cli/src/commands/migrate.ts)。 - 传入
--yes(或-y)可跳过确认提示,适合脚本化、无人值守执行。
完整参数说明
| 参数 | 说明 |
|---|---|
--server-addr <url> | 源服务器 Base URL |
--api-key <key> | 源服务器 API Key |
--dest-server <url> | 目标服务器 Base URL(必填) |
--dest-api-key <key> | 目标服务器 API Key(必填) |
--batch-size <n> | 书签迁移的分页大小,默认 50,最大 100 |
-y,--yes | 跳过确认提示 |
提示:
--batch-size在源码中会通过Math.min(Number(v || 50), MAX_NUM_BOOKMARKS_PER_PAGE)进行钳制,MAX_NUM_BOOKMARKS_PER_PAGE定义于 packages/shared/types/bookmarks.ts,即使传入超过 100 的值也会被自动限制在 100 以内。
按需排除部分数据(源码扩展)
除文档列出的基础参数外,源码还提供了一组--exclude-*选项,允许按需裁剪迁移范围(apps/cli/src/commands/migrate.ts):
--exclude-assets:跳过资产书签的迁移--exclude-lists:不迁移列表及列表成员关系--exclude-ai-prompts:不迁移 AI 提示词--exclude-rules:不迁移规则引擎规则--exclude-feeds:不迁移 RSS 源--exclude-webhooks:不迁移 Webhook--exclude-bookmarks:跳过书签迁移--exclude-tags:不迁移标签--exclude-user-settings:不迁移用户设置
典型场景:目标服务器已存在完整的标签体系,只想迁移书签时,可组合使用--exclude-tags --exclude-lists --exclude-rules等选项精简迁移内容。
迁移过程详解:每阶段做了什么
1. 用户设置
从源服务器读取用户设置,原样写入目标服务器(apps/cli/src/commands/migrate.ts),实现上是src.users.settings.query()读取 →dest.users.updateSettings.mutate()写入。
2. 列表(保留层级)
列表迁移采用父级优先策略(apps/cli/src/commands/migrate.ts):
- 先尝试在目标端查找“同名、同图标、同描述、同类型、同查询条件、同父列表”的现有列表;找到则复用(并尽力对齐
public可见性标志),找不到则创建。 - 子列表只有在其父列表创建/匹配成功之后才会处理,从而完整保留层级结构。
- 迁移过程中会建立
srcId -> destId的映射表,供后续规则与书签的列表归属使用。
3. RSS 源
逐条读取源端 RSS 源,按name、url、enabled在目标端创建,并建立新旧 ID 映射(apps/cli/src/commands/migrate.ts)。
4. AI 提示词
读取源端自定义提示词列表,逐个在目标端创建text与appliesTo字段;若创建后的默认启用状态与源端不一致,再调用更新接口对齐enabled状态(apps/cli/src/commands/migrate.ts)。
5. Webhook
只迁移 Webhook 的url与events事件配置;由于 API 无法读取 token,token 一律不迁移(apps/cli/src/commands/migrate.ts)。迁移完成后需要在目标端手动重新配置认证 token。
6. 标签(按名称确保存在)
- 遍历源端标签,按
name在目标端创建;目标端已存在同名标签时忽略重复错误(apps/cli/src/commands/migrate.ts)。 - 之后重新拉取目标端标签列表,建立“标签名 → 目标端 ID”的映射,供规则重映射与书签标签挂接使用。
7. 规则引擎规则(ID 重映射)
规则中引用了标签、列表、RSS 源等实体的 ID,迁移时必须把旧 ID 替换为目标端对应实体的新 ID(apps/cli/src/commands/migrate.ts):
- 条件:
hasTag中的tagId、importedFromFeed中的feedId,以及and/or组合条件会被递归重映射; - 事件:
tagAdded/tagRemoved的tagId、addedToList/removedFromList的listIds会被重映射; - 动作:
addTag/removeTag的tagId、addToList/removeFromList的listId会被重映射。
注意:规则迁移依赖标签、列表、RSS 源的 ID 映射表。源码中的规则迁移步骤只有在--exclude-rules、--exclude-lists、--exclude-feeds、--exclude-tags四个选项均未启用时才会执行(apps/cli/src/commands/migrate.ts),即排除了列表/源/标签后,规则也不会迁移。
8. 书签(链接、文本与资产)
书签迁移是整个流程的核心,按分页游标分批读取源端书签(apps/cli/src/commands/migrate.ts):
- 链接书签:按
url创建,目标端相同 URL 已存在时会被去重,但后续仍会为其挂接标签与列表; - 文本书签(笔记):迁移
text内容与可选的sourceUrl; - 资产书签:先从源服务器下载原始文件(
GET /api/assets/{assetId},携带源端 Bearer token),再以 multipart 表单上传到目标服务器(POST /api/assets),最后用返回的新assetId创建书签;下载或上传失败的资产会被跳过并计入 skipped 统计,不影响其余书签; - 书签创建后,会按名称把源端标签挂接到新书签(保留
attachedBy归属信息),并通过之前建立的列表 ID 映射把书签加入对应的目标端列表。
每条书签会保留title、archived、favourited、note、summary、createdAt、source等元信息;迁移时源 URL 通过srcServer/srcApiKey传入,目标上传地址通过destServer/destApiKey传入,这意味着两端服务器均需能被 CLI 所在机器访问。
迁移前需要了解的预期行为
- 列表以父级优先的顺序重建,层级关系完整保留。
- RSS 源、提示词、Webhook、标签按“值”重建(按内容/名称,而非按 ID)。
- 规则在所有 ID(标签、列表、RSS 源)重映射为目标端对应 ID 之后创建。
- 每条书签创建后,都会自动挂上正确的标签并加入正确的列表。
注意事项与建议
- Webhook 认证 token 必须迁移后在目标端手动重新填写,这是 API 层面的硬限制。
- 若目标服务器已包含数据,重复的链接会被去重;即便如此,标签和列表归属仍会应用到已存在的书签上,不会丢失关联关系。
- 迁移是长时任务,建议在网络稳定、负载较低的时段执行,并保持终端会话不被中断(必要时配合
--yes与nohup/tmux等方式运行)。
故障排查
命令中途退出怎么办
migrate命令整体上不是原子操作,中途失败后可以直接重跑,但需要注意各类数据的幂等性不同(apps/cli/src/commands/migrate.ts 在异常时会打印失败原因并退出):
- 标签与列表:已存在的会被直接复用,不会重复创建;
- 链接书签:URL 去重避免产生重复链接;笔记与资产书签则会被重新创建(资产书签可能因此产生重复,需人工核对);
- 规则、Webhook、RSS 源:会再次创建,重跑后需要手动清理目标端重复的旧记录;
- 进度日志:每阶段的进度输出会明确显示已完成的量,可根据日志判断中断点与剩余进度。
性能与负载
如果源或目标服务器处于高负载状态,请调小--batch-size(例如--batch-size 25)来降低单页请求压力;反之,希望加快迁移时可尝试调大,但不会超过 100 的上限。
其他排查思路
- 确认两端 API Key 有效且未过期:可先用
karakeep --server-addr <url> --api-key <key> whoami验证连通性与鉴权(whoami命令定义于 apps/cli/src/commands/whoami.ts)。 - 确认两端版本兼容:迁移通过标准 tRPC/HTTP API 进行,若目标端为旧版本,建议先升级目标端再迁移。
- 资产迁移失败时,命令会跳过该资产并累计 skipped 数量,可先定位是源端下载失败还是目标端上传失败(如存储配额、上传大小限制),再决定重跑或手动处理。
相关资源
- CLI 命令注册入口:apps/cli/src/index.ts
- 迁移命令完整实现:apps/cli/src/commands/migrate.ts
- CLI 与服务器通信层:apps/cli/src/lib/trpc.ts
- CLI 配置与默认服务器地址:apps/cli/src/lib/config.ts
- CLI 包信息与安装方式:apps/cli/package.json
- 当前版本文档(含本主题的未版本化版本):docs/docs/06-administration/06-server-migration.md
- 命令行集成综述:docs/docs/05-integrations/02-command-line.md
【免费下载链接】hoarderA self-hostable bookmark-everything app (links, notes and images) with AI-based automatic tagging and full text search项目地址: https://gitcode.com/GitHub_Trending/ho/hoarder
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考