Karakeep(Hoarder)本地开发环境搭建完整指南:一键脚本、手动配置与 Docker Compose 全流程
【免费下载链接】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 本地开发环境搭建实战指南,围绕官方开发文档(docs/versioned_docs/version-v0.31.0/08-development/01-setup.md)展开,覆盖start-dev.sh一键启动、Node 24 + corepack + pnpm 手动安装、环境变量与数据库初始化、Meilisearch 与无头 Chrome 依赖、Web/Workers/Mobile/浏览器扩展四大应用的启动方式,以及基于 Docker Compose 的容器化开发环境。读完本文,你将掌握从零启动整套 Karakeep 前后端开发环境所需的全部命令、配置与排错要点。
一、开发环境概览:一套本地开发环境由哪些进程组成
Karakeep(原 Hoarder)是一个基于 pnpm workspace 的 monorepo,根目录的 package.json 定义了 Turbo 任务编排,仓库主要包含以下可独立运行的应用:
apps/web:Next.js 前端 Web 应用(脚本pnpm web,对应pnpm --filter @karakeep/web run dev);apps/workers:后台 Worker 应用(脚本pnpm workers),负责爬取、索引、导入、推理等异步任务;apps/mobile:基于 Expo 的 iOS / Android 移动端;apps/browser-extension:基于 Vite + CRX 的浏览器扩展;packages/db:基于 Drizzle ORM 的 SQLite 数据库包,提供迁移能力。
要让整套环境真正“跑起来”,除了上述应用本身,还需要两个外部依赖:Meilisearch(全文搜索与向量检索的提供方)和无头 Chrome(Worker 爬取网页时的浏览器环境)。开发文档明确提醒:Web 应用在没有任何依赖的情况下也能基本运行,但搜索功能必须依赖 Meilisearch,新收藏的书签也只有在 Workers 运行时才会被爬取和索引。
二、快速开始:一条命令启动整套开发环境
开发文档推荐的首选路径是仓库根目录下的./start-dev.sh:
./start-dev.sh该脚本会自动完成以下工作(与 start-dev.sh 源码一一对应):
- 启动 Meilisearch:通过
docker run -d -p 7700:7700 --name karakeep-meilisearch getmeili/meilisearch:v1.41.0启动(当前仓库中使用的镜像版本为 v1.41.0,v0.31.0 版本文档中写的是 v1.37.0,以仓库实际为准); - 启动无头 Chrome:
docker run -d --init -p 127.0.0.1:9222:9222 --name karakeep-chrome ghcr.io/karakeep-app/karakeep-chrome:release,并附带--disable-gpu --disable-dev-shm-usage --hide-scrollbars --disable-blink-features=AutomationControlled --window-size=1440,900等参数; - 安装依赖:若根目录不存在
node_modules,自动执行pnpm install; - 执行数据库迁移:运行
pnpm run db:migrate; - 并行启动 Web 与 Workers:后台执行
pnpm web与pnpm workers,并等待 Web 应用在 3000 端口就绪(使用nc -z localhost 3000最多探测 30 秒)。
脚本启动后会输出三个可直接访问的服务地址:
- Web 应用:http://localhost:3000
- Meilisearch:http://localhost:7700
- Chrome 调试器:http://localhost:9222
前置条件:本机已安装并运行 Docker,且已安装 pnpm(安装方式见下文手动搭建章节)。
值得注意的细节:脚本会先通过lsof -i :端口检查 7700 与 9222 端口是否已被占用,已占用则复用现有容器而非重复启动;DATA_DIR会从环境变量或.env文件中读取,若不存在会自动创建目录;按Ctrl+C时,trap cleanup SIGINT SIGTERM会依次 kill 掉 Web/Workers 进程并docker stop/docker rm清理两个容器。
三、手动搭建:从零配置开发环境
如果希望完全掌控每一步,可以走手动搭建路线。Karakeep 的开发环境对 Node 版本有明确要求,且依赖 corepack 来管理包管理器版本。
3.1 安装 Node.js 24 与启用 corepack
Karakeep 要求 Nodev24版本,推荐使用 nvm 安装:
$ nvm install 24安装后验证版本:
$ node --version v24.14.0项目使用 corepack 锁定包管理器版本——根目录 package.json 中声明了"packageManager": "pnpm@11.2.1"。由于 corepack 随 Node 一起分发,安装 Node 后通常无需额外操作,可先确认其存在:
$ command -v corepack /home/<user>/.nvm/versions/node/v24.14.0/bin/corepack若尚未启用,执行:
$ corepack enable容器化开发环境同样遵循这一约定:docker/Dockerfile.dev 基于node:24-alpine构建,并在镜像内执行corepack enable。
3.2 安装依赖:pnpm install
在仓库根目录执行:
$ pnpm install一次成功的安装输出大致如下:
Scope: all 20 workspace projects Lockfile is up to date, resolution step is skipped Packages: +3129 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Progress: resolved 0, reused 2699, downloaded 0, added 3129, done devDependencies: + @karakeep/prettier-config 0.1.0 <- tooling/prettier . prepare$ husky └─ Done in 45ms Done in 5.5s从中可以看到:仓库共 20 个 workspace 子项目;安装过程会触发prepare钩子执行 husky(Git 钩子工具);依赖复用率较高(reused 2699)。安装完成后即可继续后续配置。
四、首次配置:环境变量与数据库初始化
4.1 准备环境变量
开发环境的每个应用都需要读取环境变量。最省事的做法是:在仓库根目录配置一次.env,然后在各应用目录(如apps/web、apps/workers)以及packages/db下用符号链接指向它。
首先从模板复制:
$ cp .env.sample .env仓库根目录的 .env.sample 内容非常精简,仅包含两个占位变量:
# See https://docs.karakeep.app/configuration for more information DATA_DIR=<path> NEXTAUTH_SECRET=<secret>开发文档强调的四个关键变量如下:
| 变量 | 作用 | 说明 |
|---|---|---|
DATA_DIR | 数据库与资产的存放目录 | 唯一必填项。建议使用绝对路径,让所有应用指向同一目录 |
NEXTAUTH_SECRET | 用于签名 JWT 的随机字符串 | 缺失时登录功能将不可用!可用openssl rand -base64 36生成 |
MEILI_ADDR | Meilisearch 服务地址 | 未设置时搜索功能会被禁用;本地可用http://127.0.0.1:7700 |
OPENAI_API_KEY | OpenAI API 密钥 | 仅在开发环境启用 AI 自动打标签(auto tag inference)时需要 |
从源码层面看,所有环境变量的解析集中在 packages/shared/config.ts:它用 zod 定义了完整的allEnvschema 并对process.env进行校验。其中有几个与本文直接相关的实现细节:
DATA_DIR默认值为空字符串,ASSETS_DIR未设置时会回退为path.join(DATA_DIR, "assets");NEXTAUTH_SECRET通过signingSecret()延迟求值,未设置时会直接抛出NEXTAUTH_SECRET is not set异常——这与文档“登录将不可用”的警告在代码层面完全吻合;MEILI_ADDR未设置时搜索链路不会初始化索引;- 所有配置最终通过
serverConfigSchema.parse(process.env)生成只读的serverConfig,并单独挑出clientConfig暴露给前端,避免敏感信息泄漏。
4.2 初始化数据库
环境变量就绪后,在仓库根目录执行:
$ pnpm run db:migrate该命令实际执行pnpm --filter @karakeep/db run migrate(见 package.json),即packages/db中的tsx migrate.ts。packages/db/migrate.ts 的实现很简洁:若serverConfig.degradedMode(降级模式)开启则跳过迁移,否则调用 Drizzle 的migrate(db, { migrationsFolder: "./drizzle" })。迁移 SQL 文件位于packages/db/drizzle/目录(从0000_luxuriant_johnny_blaze.sql到0025_aspiring_skaar.sql),均由drizzle-kit generate生成。数据库本身是 SQLite(better-sqlite3驱动,见 packages/db/package.json)。
五、本地依赖:Meilisearch 与 Chrome
5.1 Meilisearch:全文搜索与向量检索的提供方
Meilisearch 是 Karakeep 全文搜索(未来还包括 embeddings 向量搜索)的提供方。手动启动方式:
$ docker run -p 7700:7700 getmeili/meilisearch:v1.41.0两个实操要点:
- 如需跨重启保留索引数据,请挂载持久化卷;
- 若需对整个书签集合重新建索引,可在 Web 应用的**管理面板(admin panel)**中触发全量 re-index。
在 Docker 开发环境中,Meilisearch 以独立 service 运行,并设置了MEILI_NO_ANALYTICS=true与MEILI_MASTER_KEY(见下文第九章与 docker/docker-compose.dev.yml)。
5.2 Chrome:Worker 爬虫的浏览器环境
Worker 应用启动时会自动启动无头 Chrome用于爬取页面,开发环境下通常无需手动干预。从配置角度看,爬虫连接 Chrome 的方式由BROWSER_WEB_URL(HTTP 调试端口,如http://chrome:9222)或BROWSER_WEBSOCKET_URL等变量控制(见 packages/shared/config.ts 中crawler配置段)。CRAWLER_HEADLESS_BROWSER默认开启,即爬虫默认依赖无头浏览器抓取页面内容。
六、启动 Web 应用与 Workers
6.1 Web 应用
在仓库根目录运行:
$ pnpm web然后访问 http://localhost:3000 即可。
需要特别说明的是依赖关系(开发文档中的 NOTE 原文强调):
Web 应用在没有依赖的情况下也能基本运行。但搜索功能只有在 meilisearch 运行时才可用;此外,新添加的书签只有在 workers 运行时才会被爬取和索引。
换句话说,纯看界面可以不启动任何外部服务,但要完整体验“保存书签 → 自动爬取 → 全文搜索 → AI 打标签”的闭环,Meilisearch、Workers 与 OpenAI 配置缺一不可。
6.2 Workers
在仓库根目录另开终端运行:
$ pnpm workersWorkers 承载了 Karakeep 的大量异步能力。从 apps/workers 的源码结构看,Worker 类型包括:crawler(页面爬取)、inference(AI 推理/打标签/摘要)、search(搜索索引)、embeddings(向量嵌入)、import(导入)、feed(RSS 订阅)、webhook、backup、ruleEngine、assetPreprocessing 等,分别对应apps/workers/workers/下的各个 Worker 文件。WORKERS_ENABLED_WORKERS/WORKERS_DISABLED_WORKERS环境变量可以按需启停特定 Worker(见 packages/shared/config.ts)。
七、移动端开发(iOS & Android)
7.1 前置条件
要本地构建并运行移动应用,需要:
- iOS 开发:macOS 电脑、从 App Store 安装 Xcode、随 Xcode 附带的 iOS Simulator;
- Android 开发:安装 Android Studio、配置 Android SDK、准备 Android Emulator 或真机。
详细的本地开发环境搭建可参考 Expo 官方文档(local app development 指南)。
7.2 构建并运行
进入移动端目录并预构建原生工程:
$ cd apps/mobile $ pnpm exec expo prebuild --no-installiOS:
$ pnpm exec expo run:ios应用会被安装并启动到模拟器中。
iOS 排错:如果遇到类似xcrun: error: SDK "iphoneos" cannot be located的错误,可能是 Xcode 开发者目录未指向正确位置,可执行:
sudo xcode-select -s /Applications/Xcode.app/Contents/DeveloperAndroid:
$ pnpm exec expo run:android应用会被安装并启动到模拟器/真机上。
代码改动会触发热重载(hot reload);但安装新依赖包后需要重启 expo server才能生效。
从当前仓库 apps/mobile/package.json 的脚本来看,移动端提供了更细分的运行入口:pnpm ios/pnpm android(development 变体)、ios:preview/android:preview(独立 bundle ID、无需 devserver 的预览变体)、ios:release/android:release(接近生产构建的 release 变体),并通过APP_VARIANT环境变量控制。日常开发 90% 的情况下使用 development 变体即可;如果从旧版本升级后构建失败(如 Expo 大版本升级残留了过期的原生构建产物),可先执行pnpm run clean:workspaces、pnpm install与pnpm --filter @karakeep/mobile clean:prebuild清理后重新构建。
八、浏览器扩展开发
浏览器扩展的开发步骤如下:
$ cd apps/browser-extension $ pnpm dev执行后,Vite 会生成dist产物目录(扩展开发服务器默认运行在 http://localhost:5174)。然后:
- 打开浏览器扩展管理页(Chrome 的
chrome://extensions或 Brave 对应页面); - 开启“开发者模式”(Developer mode);
- 点击“Load unpacked”(加载已解压的扩展程序),选择
apps/browser-extension/dist目录; - 扩展会出现在扩展列表中。
开发模式下,打开和关闭扩展弹窗即会重新加载代码,无需手动刷新整个扩展。从 apps/browser-extension/package.json 可以看到,dev脚本直接调用vite,构建链路为tsc && vite build,并依赖@crxjs/vite-plugin来生成符合 Chrome Manifest V3 规范的扩展产物。
九、基于 Docker Compose 的开发环境
如果手动搭建过于繁琐,官方文档还提供了一条容器化路径,在仓库根目录执行:
$ docker compose -f docker/docker-compose.dev.yml upv0.31.0 版本文档对这套方案的评价比较谨慎(原文称“这套方案对我来说不算特别可靠”),但当前仓库中的 docker/docker-compose.dev.yml 已经演进得相当完整,共编排了五个服务:
| 服务 | 作用 |
|---|---|
prep | 一次性任务:创建DATA_DIR(默认为/data)、执行pnpm install --frozen-lockfile、执行pnpm run db:migrate,为其他服务准备好依赖与数据库 |
web | 运行pnpm web(Next.js dev server),映射宿主机 3000 端口,开启WATCHPACK_POLLING/CHOKIDAR_USEPOLLING以在 Mac/Windows 文件同步下可靠触发热重载 |
workers | 运行pnpm workers,与本地开发行为一致 |
meilisearch | 内部服务,仅容器网络内可访问(宿主机不暴露端口),禁用遥测并挂载持久化数据卷 |
chrome | 供 Workers 使用的可远程调试 Chrome 实例,映射到 9222 端口 |
几个关键的编排细节值得开发者注意:
- 默认环境变量:即使不创建
.env,compose 文件也会通过${VAR:-default}语法注入合理默认值——DATA_DIR=/data、MEILI_ADDR=http://meilisearch:7700、NEXTAUTH_URL=http://localhost:3000、NEXTAUTH_SECRET=super-secure-nextauth-secret; - 必须覆盖的变量:
NEXTAUTH_SECRET默认值只用于开发演示,正式使用前应至少通过.env覆盖(用openssl rand -base64 36生成);可选的OPENAI_API_KEY等也建议写进.env; - 数据挂载:
data:${DATA_DIR:-/data}默认将数据存入 Docker volume;如需改用宿主机目录,可修改 volume 映射为/path/to/your/directory:/data; - 共享卷:所有应用容器把宿主仓库挂载到
/app,并共享node_modules(依赖装在 Linux 容器内)与pnpm-store(pnpm 缓存)两个卷; - 日志与清理:
docker compose logs -f web workers跟踪日志;docker compose down停止全部服务,改动 Node 依赖或 Dockerfile 后需加--build重建;docker compose down -v可彻底清空数据卷,获得全新状态。
十、常见问题与排查建议
结合开发文档与仓库源码,整理开发中最高频的几类问题及对应排查方向:
- 登录/认证失效:检查
NEXTAUTH_SECRET是否设置。源码层面 packages/shared/config.ts 会在其缺失时直接抛错,确保所有应用(尤其是 Web 与 Workers)读取的是同一个.env(建议符号链接共享); - 搜索不可用:确认
MEILI_ADDR已设置且 Meilisearch 在 7700 端口可达(docker ps或直接访问 http://localhost:7700);本地重启后索引数据丢失,可挂载持久化卷并在管理面板触发全量 re-index; - 新收藏书签没有被爬取/索引:确认
pnpm workers正在运行;同时确认 9222 端口的无头 Chrome 可访问(BROWSER_WEB_URL指向正确); - Node 版本不匹配:
node --version必须是 v24 系列,nvm 切换后记得重新corepack enable与pnpm install; - iOS 构建报
xcrun: error: SDK "iphoneos" cannot be located:执行sudo xcode-select -s /Applications/Xcode.app/Contents/Developer修正开发者目录; - 移动端升级后构建失败:清理过期原生产物,按
pnpm run clean:workspaces→pnpm install→pnpm --filter @karakeep/mobile clean:prebuild顺序重建; - 端口冲突:
start-dev.sh对 7700/9222 端口已有占用检测逻辑,若手动启动遇到冲突,可先停掉占用进程或改用其他端口并同步调整环境变量。
结语
Karakeep 的开发环境横跨 Web、Workers、移动端与浏览器扩展四个应用形态,外加 Meilisearch 与无头 Chrome 两个外部依赖,初次搭建容易在环境变量与依赖顺序上踩坑。本文以官方开发文档为骨架,结合仓库内 start-dev.sh、.env.sample、package.json、packages/shared/config.ts、docker/docker-compose.dev.yml 等真实源码,把“一键脚本、手动搭建、容器化开发”三条路径完整走通。上手时优先尝试./start-dev.sh,需要精细化控制时再按手动流程逐步配置;完整的变量清单还可参考 docs/docs/03-configuration/01-environment-variables.md,目录结构说明见 docs/docs/08-development/02-directories.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),仅供参考