news 2026/9/10 8:18:37

Karakeep(前身 Hoarder)自托管书签应用全解析:AI 自动打标签、全文搜索与 Docker 部署实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Karakeep(前身 Hoarder)自托管书签应用全解析:AI 自动打标签、全文搜索与 Docker 部署实战

Karakeep(前身 Hoarder)自托管书签应用全解析:AI 自动打标签、全文搜索与 Docker 部署实战

【免费下载链接】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)是一个以"自托管优先"为设计理念的开源"书签一切"应用,支持收藏链接、速记笔记、图片与 PDF,并借助 AI 实现自动打标签与摘要、全文与语义搜索。本文以仓库根目录的 README.md 为骨架,结合 docker/docker-compose.yml、packages/shared/config.ts、apps/workers/index.ts 等源码与 docs 目录下的官方文档,完整梳理其功能全景、技术栈、Docker 部署步骤、环境变量与 AI 推理配置,帮助读者在自建服务器上一站式落地这套"数据囤积者"的收藏工作流。

项目定位与命名来源

Karakeep 的定位是"self-hostable bookmark-everything app with a touch of AI for the data hoarders"——一个面向数据囤积者的、带一点 AI 能力的自托管收藏应用。它不只是收藏链接,还可以承载笔记、图片、PDF,并围绕收藏内容提供搜索、归档、协作与自动化能力。

项目名称 Karakeep 的灵感来自阿拉伯语单词"كراكيب"(karakeeb),这是一个口语化词汇,泛指杂七杂八、看似凌乱却往往承载个人价值或潜在用处的小物件,类似于"装满了舍不得扔的东西的抽屉"。这个命名精准呼应了产品的核心使用场景:把散落各处、难以归类的内容统一收进来,供日后随时翻找。

功能特性全景

README 中列出的功能覆盖了从"收藏"到"消费"再到"自动化治理"的完整链路,逐项展开如下:

收藏与内容捕获

  • 收藏链接、速记笔记、图片与 PDF:三种基础内容类型(link / note / asset),并支持批量操作(Bulk actions)。
  • 自动抓取链接标题、描述与图片:由爬虫工作器完成,链接被收藏后自动补充元数据与预览图。
  • Mark 并保存收藏内容中的高亮(highlights):可以在已收藏的阅读内容上标记高亮片段并保存。
  • 浏览器扩展快速收藏:提供 Chrome 插件、Firefox 扩展与 Safari 扩展,对应源码位于 apps/browser-extension。
  • iOS / Android 原生应用:源码位于 apps/mobile,并支持移动端离线阅读
  • 导入器:支持从 Chrome、Pocket、Linkwarden、Omnivore、Tab Session Manager 导入收藏,并可借助 floccus 与浏览器书签自动同步。

组织、检索与消费

  • 列表(Lists):将收藏整理进不同的列表,并支持多人协作同一个列表
  • 全文与语义搜索:基于 Meilisearch 的全文索引,加上 embedding 向量化后的语义搜索,覆盖所有已存储内容。
  • AI 自动打标签与摘要:基于 LLM(支持通过 Ollama 使用本地模型),自动为收藏内容生成标签和摘要,标签语言可通过INFERENCE_LANG配置。
  • 规则引擎:基于规则的自动化管理,例如按条件自动打标签、归档等,由独立的ruleEngine工作器驱动(见 apps/workers/index.ts)。
  • OCR 图片文字提取:默认基于 tesseract.js,也可切换为 LLM 驱动的 OCR。
  • RSS 自动囤积(Auto hoarding):订阅 RSS 源后自动把新内容收藏入库。
  • REST API 与多客户端:项目提供 OpenAPI 规格 与官方 SDK,docs/docs/api 下收录了完整的 API 文档。

归档与防链接腐坏

  • 整页归档(Full page archival):使用 monolith 将页面完整保存为单文件 HTML,抵御链接腐坏(link rot)。
  • 自动视频归档:使用 yt-dlp 下载页面视频。
  • 爬虫可选的PDF 快照、全页截图、banner 图本地缓存等,均在环境变量文档中有对应开关(见下文"爬虫配置")。

平台与体验

  • 多语言支持:通过 Weblate 管理翻译。
  • SSO 支持:支持 OIDC 兼容的 OAuth 登录。
  • 暗色模式自托管优先的设计哲学。

技术栈与仓库结构

README 明确列出的技术栈如下:

组件用途
Next.js(App Router)Web 应用主体
Drizzle数据库 ORM 与迁移
NextAuth认证
tRPC客户端与服务端通信
Puppeteer爬取收藏的网页
OpenAIAI 打标签等推理(可通过 Ollama 换本地模型)
Meilisearch全文内容搜索

仓库是一个 pnpm + Turbo 的 monorepo,根 package.json 提供pnpm devpnpm buildpnpm db:migrate等脚本。官方 目录结构文档 给出了清晰的模块划分:

  • 应用层apps/web(主 Web 应用)、apps/workers(后台工作器)、apps/mobile(React Native 移动应用)、apps/browser-extension(浏览器扩展)、apps/landing(落地页)。
  • 共享包packages/db(数据库 schema 与迁移)、packages/trpc(大部分业务逻辑以 tRPC 路由形式存在)、packages/shared(各应用共享的日志与配置)、packages/shared-server(队列、资产存储等仅服务端可用的服务)、packages/plugins(可插拔服务实现,如文件系统与 S3 存储)。
  • 工具链tooling/typescripttooling/eslinttooling/prettiertooling/tailwind存放共享配置。

从 apps/workers/index.ts 可以看到,后台按职责拆成了 12 类工作器:crawlerlowPriorityCrawlerembeddingsinferencesearchadminMaintenancevideofeedassetPreprocessingwebhookruleEnginebackup,外加一个import轮询工作器;它们各自消费独立的队列(如LinkCrawlerQueueOpenAIQueueSearchIndexingQueue),并通过WORKERS_ENABLED_WORKERS/WORKERS_DISABLED_WORKERS两个环境变量按需启停。

Docker 部署实战

Docker Compose 是官方推荐、也是最快上手的部署方式,详见 Docker 安装指南。

1. 创建目录并下载 compose 文件

新建一个目录(例如karakeep-app),把官方提供的 docker/docker-compose.yml 放进去。该文件定义了三个服务:

  • web:主应用,镜像为ghcr.io/karakeep-app/karakeep:${KARAKEEP_VERSION:-release},端口3000:3000,数据卷data:/data,并通过环境变量把MEILI_ADDR指向 meilisearch、BROWSER_WEB_URL指向 chrome 服务;DATA_DIR固定为/data(官方注释强调"不要改",要改数据目录应改卷映射)。
  • chrome:爬虫用的 headless 浏览器容器,镜像ghcr.io/karakeep-app/karakeep-chrome:release,启动参数包含--disable-gpu--disable-dev-shm-usage--hide-scrollbars等。
  • meilisearch:搜索服务,镜像getmeili/meilisearch:v1.41.0,启用MEILI_NO_ANALYTICS: "true",数据卷meilisearch:/meili_data

2. 填写 .env 环境变量

在 compose 文件同目录创建.env,最小可用配置如下:

KARAKEEP_VERSION=release NEXTAUTH_SECRET=super_random_string MEILI_MASTER_KEY=another_random_string NEXTAUTH_URL=http://localhost:3000

要点:

  • 两个随机字符串务必替换,可用openssl rand -base64 36生成;MEILI_MASTER_KEY建议用openssl rand -base64 36 | tr -dc 'A-Za-z0-9'生成(避免特殊字符)。
  • NEXTAUTH_URL要指向你实际访问 Karakeep 的地址,否则登出等场景会跳转到错误地址。
  • KARAKEEP_VERSION=release会拉取最新稳定版;要控制升级节奏可固定到具体版本(如0.10.0)。
  • 每次修改.env后都需要重新执行docker compose up使配置生效。

3. 配置 AI(可选但强烈推荐)

要启用自动打标签,在.env中追加OPENAI_API_KEY=<key>即可。也可以改用其他 OpenAI 兼容服务或本地 Ollama,见下文"AI Provider 配置"一节。

4. 启动与验证

docker compose up -d

随后访问http://localhost:3000即可看到登录页。持久化存储与服务间联调(web ↔ chrome ↔ meilisearch)已由 compose 文件处理。

5. 升级

升级方式取决于KARAKEEP_VERSION的取值:

  • 固定版本:改版本号后重新docker compose up -d拉取新镜像;
  • 使用release:执行docker compose up --pull always -d强制拉取最新版本。

若自定义 compose 仍在使用旧版 Alpine Chrome 镜像,需参考 Chrome 镜像迁移指南;升级/迁移 Meilisearch 版本时,可参考 故障排查文档。

环境变量配置详解

Karakeep 以环境变量为主要配置入口,全部变量统一定义在 packages/shared/config.ts(使用 zod schema 做解析、默认值与校验),完整参数说明见 环境变量文档。以下是按功能域划分的核心变量:

基础与安全

变量必填默认值说明
PORT3000Web 服务监听端口;用 Docker 时不要改它,改外部端口映射即可
WORKERS_PORT0(随机)工作器导出 Prometheus 指标的端口(/metrics
WORKERS_HOST127.0.0.1指标监听地址,容器内运行需改为可外部访问的地址
WORKERS_ENABLED_WORKERS未设置逗号分隔的工作器白名单:crawler,inference,search,adminMaintenance,video,feed,assetPreprocessing,webhook,ruleEngine,backup
WORKERS_DISABLED_WORKERS未设置逗号分隔的工作器黑名单,优先级高于WORKERS_ENABLED_WORKERS
LOG_LEVELdebug按 winston 的日志级别定义,生产环境建议noticewarning
DATA_DIR未设置持久数据目录(数据库所在处),未设置ASSETS_DIR时资产也存于此
ASSETS_DIR${DATA_DIR}/assets爬取资产的存储路径
NEXTAUTH_URL未设置服务器对外地址
NEXTAUTH_SECRET未设置用于签名 JWT 的随机串
MEILI_ADDR未设置Meilisearch 地址,未设置则搜索被禁用
MEILI_MASTER_KEY仅生产 + 启用搜索未设置Meilisearch 主密钥,开发环境不需要
MAX_ASSET_SIZE_MB50允许上传的资产大小上限(MB)
DB_WAL_MODEfalse为 SQLite 开启 WAL 模式提升性能;数据库在网络盘上时不要开启
DISABLE_NEW_RELEASE_CHECKfalse关闭管理面板中的新版本检查

认证与注册

变量默认值说明
DISABLE_SIGNUPSfalse禁止新用户注册
DISABLE_PASSWORD_AUTHfalse仅允许 OAuth 登录
EMAIL_VERIFICATION_REQUIREDfalse注册需邮箱验证(需配置 SMTP)
OAUTH_WELLKNOWN_URL未设置OAuth 提供商的 OpenID 配置地址
OAUTH_CLIENT_ID/OAUTH_CLIENT_SECRET未设置OAuth 客户端凭证
OAUTH_ID_TOKEN_SIGNED_RESPONSE_ALG未设置ID token 的 JWS 签名算法,可选RS256EdDSA;与提供商实际算法不符会导致回调报 JWT 算法错误
OAUTH_SCOPEopenid email profile请求的 scope 列表(空格分隔)
OAUTH_PROVIDER_NAMECustom Provider登录页显示的提供商名
OAUTH_AUTO_REDIRECTfalse仅 OAuth 认证时自动跳转提供商
OAUTH_TIMEOUT3500等待提供商响应毫秒数,遇outgoing request timed out可调大

注意:仅支持 OIDC 兼容的 OAuth 提供商,且回调地址需配置为<NEXTAUTH_URL>/api/auth/callback/custom

资产存储:本地磁盘 vs S3

默认使用本地文件系统,传入 S3 端点后自动切换为 S3 兼容对象存储:

变量说明
ASSET_STORE_S3_ENDPOINTS3 端点 URL(如 MinIO),设置即启用 S3
ASSET_STORE_S3_REGIONS3 区域
ASSET_STORE_S3_BUCKET桶名(使用 S3 时必填)
ASSET_STORE_S3_ACCESS_KEY_ID/ASSET_STORE_S3_SECRET_ACCESS_KEYS3 认证凭证
ASSET_STORE_S3_FORCE_PATH_STYLEMinIO 等需设为true

文档明确警告:存储后端一经写入数据即不可随意切换,否则需要手工迁移既有资产,部署前应规划好存储方案。

爬虫配置(Crawler)

变量默认值说明
CRAWLER_NUM_WORKERS1并发爬取任务数
BROWSER_WEB_URL/BROWSER_WEBSOCKET_URL未设置浏览器调试地址;都不设置时退化为纯 HTTP 请求,跳过截图与 JS 执行
CRAWLER_STORE_SCREENSHOTtrue存储网页截图(作为图片提取失败的兜底)
CRAWLER_FULL_PAGE_SCREENSHOTfalse存储整页截图(磁盘占用高,默认关闭)
CRAWLER_STORE_PDFfalse存储页面 PDF 快照(默认关闭)
CRAWLER_FULL_PAGE_ARCHIVEfalse整页本地归档(默认关闭,仅归档可读文本)
CRAWLER_VIDEO_DOWNLOADfalse用 yt-dlp 下载页面视频
CRAWLER_VIDEO_DOWNLOAD_MAX_SIZE50视频最大体积(MB),-1禁用限制
CRAWLER_JOB_TIMEOUT_SEC60爬取任务超时
CRAWLER_ENABLE_ADBLOCKERtrue爬虫内置广告拦截
CRAWLER_ENABLE_AUTOCONSENTtrue自动选择退出支持的同意弹窗
CRAWLER_YTDLP_ARGS/CRAWLER_MONOLITH_ARGS[]追加 yt-dlp / monolith 参数,多个参数用%%分隔
BROWSER_COOKIE_PATH未设置加载到浏览器上下文的 cookie JSON 文件路径(数组,name/value必填,domainexpireshttpOnlysameSite等可选)

OCR 配置

变量默认值说明
OCR_CACHE_DIR$TEMP_DIRtesseract 模型下载目录
OCR_LANGSeng逗号分隔的语言码,置空可禁用 OCR
OCR_CONFIDENCE_THRESHOLD50置信度阈值(0–100),低于阈值不保存识别文本
OCR_USE_LLMfalse改用推理模型(OpenAI/Ollama)做 OCR,复杂图片效果更好

Webhook 配置

变量默认值说明
WEBHOOK_TIMEOUT_SEC5webhook 请求超时
WEBHOOK_RETRY_TIMES3重试次数

Webhook 触发时请求头携带Authorization: Bearer <WEBHOOK_TOKEN>,请求体为包含jobIdtypebookmarkIduserIdurloperation的 JSON。

SMTP 与代理

  • SMTPSMTP_HOSTSMTP_PORT(默认587)、SMTP_SECURESMTP_USERSMTP_PASSWORDSMTP_FROM,用于注册邮箱验证等邮件功能。
  • 代理CRAWLER_HTTP_PROXY/CRAWLER_HTTPS_PROXY(支持逗号分隔多代理随机选用,作用于爬取、RSS 拉取与 webhook)、CRAWLER_NO_PROXY(绕过列表)、CRAWLER_ALLOWED_INTERNAL_HOSTNAMES(默认拦截解析到内网/回环/link-local 地址的请求,用点前缀支持域名通配)。

可观测性

变量默认值说明
OTEL_TRACING_ENABLEDfalse启用 OpenTelemetry 分布式追踪
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT未设置追踪 OTLP 端点,未设置则打到控制台
OTEL_SAMPLE_RATE1.0追踪采样率
EVENT_LOGS_ENABLEDfalse结构化事件日志(登录、书签创建等)
PROMETHEUS_AUTH_TOKEN随机/api/metrics的 Bearer 认证令牌

AI Provider 配置:从 OpenAI 到本地 Ollama

AI 能力(自动打标签、摘要、语义搜索的 embedding)是本项目的核心卖点之一。配置全貌见 AI Provider 指南,核心规则是:OPENAI_API_KEYOLLAMA_BASE_URL至少设置其一,自动打标签才会启用

OpenAI(默认)

只需设置OPENAI_API_KEY;默认推理模型为gpt-5.6-luna(文本)、gpt-4o-mini(图片),embedding 默认text-embedding-3-small/ 1536 维,均可在.env中覆盖:

OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxx # INFERENCE_TEXT_MODEL=gpt-4.1-mini # INFERENCE_IMAGE_MODEL=gpt-4o-mini # EMBEDDING_TEXT_MODEL=text-embedding-3-small # EMBEDDING_DIMENSIONS=1536

补充说明:OPENAI_BASE_URL可指向任意 OpenAI 兼容 API(Azure、Gemini、OpenRouter、Perplexity、Cloudflare 等均可用此方式接入);OPENAI_TIMEOUT_SEC未设置时沿用 OpenAI SDK 默认 10 分钟;OPENAI_SERVICE_TIER=flex可换取更低成本(响应更慢、偶发资源不可用);OPENAI_REASONING_EFFORT控制推理模型的思考强度。

Ollama 本地推理

Ollama 提供两种接入方式,且地址必须能被 Karakeep 容器访问(不能用 localhost):

方式一:OpenAI 兼容端点(推荐),走/v1chat 接口,消息格式化更可靠:

OPENAI_API_KEY=ollama OPENAI_BASE_URL=http://ollama.mylab.com:11434/v1 INFERENCE_TEXT_MODEL=gemma3 INFERENCE_IMAGE_MODEL=llava EMBEDDING_TEXT_MODEL=embeddinggemma EMBEDDING_DIMENSIONS=768 EMBEDDING_CONTEXT_LENGTH=2048

方式二:原生 Ollama API,注意此时绝不能设置OPENAI_API_KEY(否则优先走 OpenAI):

OLLAMA_BASE_URL=http://ollama.mylab.com:11434 # INFERENCE_OUTPUT_SCHEMA=plain # 模型不支持结构化输出时需要

OLLAMA_KEEP_ALIVE控制模型在内存中的驻留时长(如5m-1m永久驻留、0即时卸载);INFERENCE_FETCH_TIMEOUT_SEC(默认 300)针对 Ollama 请求超时。

其他 OpenAI 兼容提供商

文档还给出了可直接套用的配置模板:Gemini(OPENAI_BASE_URL=https://generativelanguage.googleapis.com/v1beta,示例模型gemini-2.5-flash-lite)、OpenRouter(https://openrouter.ai/api/v1)、Perplexity(https://api.perplexity.ai)、Azure(模型名即部署名)、Cloudflare Workers AI(建议INFERENCE_OUTPUT_SCHEMA=json)。

Embedding 与语义搜索

  • 三个关键变量:EMBEDDING_TEXT_MODELEMBEDDING_DIMENSIONS(向量维度,必须与模型一致)、EMBEDDING_CONTEXT_LENGTH(默认 8000 字符,超出截断)。
  • Embedding 可独立使用另一家 OpenAI 兼容提供商:EMBEDDING_OPENAI_API_KEYEMBEDDING_OPENAI_BASE_URL,未设置时回落到对应的OPENAI_*变量。
  • 支持可变维度的模型可设EMBEDDING_TEXT_MODEL_DIMENSION_OVERRIDE,其值必须等于EMBEDDING_DIMENSIONS,否则 Karakeep 启动失败。
  • 配置好 embedding 后需开启EMBEDDING_ENABLE_AUTO_INDEXING=trueSEMANTIC_SEARCH_ENABLED(默认true)控制混合/语义搜索模式(实验性)。
  • 重要提醒:不同模型的向量互不兼容,更换 embedding 模型或维度后,需要为全部书签重新生成向量。

打标签/摘要相关调优

INFERENCE_CONTEXT_LENGTH(默认 2048 token)决定送入模型的内容量,调大提升标签质量但更费钱/费资源;INFERENCE_MAX_OUTPUT_TOKENS(默认 2048)控制生成长度;INFERENCE_LANG(默认english)指定标签语言;INFERENCE_ENABLE_AUTO_TAGGING(默认true)与INFERENCE_ENABLE_AUTO_SUMMARIZATION(默认false)分别开关自动打标签与摘要;INFERENCE_OUTPUT_SCHEMA(默认structured,可选json/plain)适配模型的结构化输出能力。此外可在"用户设置 → AI Settings"中给自动打标签的 prompt 追加自定义指令,并支持$tags$aiTags$userTags三个占位符(分别替换为全部标签、AI 标签、人工标签)。

体验 Demo 与快速上手

官方提供了在线 Demo:访问https://try.karakeep.app,使用demo@karakeep.app/demodemo登录。Demo 预置了示例内容,但处于只读模式以防滥用——适合在部署前先直观感受界面与交互。部署完成后,可以继续阅读 docs 下的使用指南(书签、列表、标签、搜索语法、导入、快速分享等),以及 命令行工具 与 MCP 服务 的接入文档,实现"LLM Agent 友好"的自动化工作流。

项目背景、动机与生态

  • 构建动机:作者长期在手机端浏览 Reddit/Twitter/Hacker News,需要把值得稍后细读的内容收藏下来;在尝试 Pocket、memos 等工具后,发现它们缺少"链接预览 + 自动打标签"的组合能力,于是决定自建。README 中也客观列举了作者参考过的同类工具(memos、mymind、raindrop、Pocket、Linkwarden、Wallabag、Shiori),这些内容可作为选型时的背景参考。
  • 翻译:项目通过 Weblate 管理多语言翻译,欢迎贡献。
  • 托管云服务:若不想自托管,官方提供 Karakeep Cloud 托管服务,订阅收入用于支持项目开发。
  • 社区渠道:官方 Discord 与 Twitter(@karakeep_app)是主要的交流渠道。
  • 许可证:项目采用 AGPL-3.0 协议(见 LICENSE)。

总结

Karakeep 把"收藏 + AI 治理 + 全文/语义检索 + 归档防腐坏"整合进一个自托管优先的 monorepo 中:Web 端由 Next.js + tRPC + Drizzle 驱动,后台按队列模型拆分成 12 类可独立启停的工作器,资产存储支持本地磁盘与 S3 双后端,AI 推理既可直连 OpenAI 也能通过 Ollama 完全本地化。对个人用户而言,按 Docker 安装指南 三步即可完成部署;对开发者而言,目录结构文档、环境变量文档 与 packages/shared/config.ts 提供了从配置到源码的完整索引,是一套相当适合自托管与二次开发的书签基础设施。

【免费下载链接】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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 8:15:10

Pandas数据分析全流程:从数据清洗到可视化实战

想聊一个很实际的问题&#xff1a;Pandas在数据分析里到底怎么用&#xff1f;很多朋友学了一堆函数&#xff0c;打开真实数据还是一脸懵。这篇文章我会从数据清洗讲到可视化&#xff0c;用一套完整的流程串起Pandas的核心操作&#xff0c;包括环境配置、类型转换、分组聚合、绘…

作者头像 李华
网站建设 2026/9/10 8:11:28

Delegatecall存储碰撞漏洞详解:从EVM存储布局到DeFi安全审计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/10 8:10:29

ESP32 RMT外设详解:从NEC协议到红外学习发射器实战

看看家里的电器遥控器&#xff0c;十个里面有八个是红外&#xff0c;电视、空调、机顶盒、风扇&#xff0c;全是那一枚小灯珠在前头闪。但你要是真拿示波器去量它的输出&#xff0c;会发现这玩意儿一点都不简单——一串宽度各异的脉冲&#xff0c;有的几百微秒&#xff0c;有的…

作者头像 李华