在 VPS 上用 Docker 部署 Karakeep:网页、图片和随手记的内容放进一个收藏库

用 Docker 部署 Karakeep,连接抓取浏览器与搜索,整理链接、图片和笔记,限制注册并验证备份恢复。

·9 minself-hosted

一个链接放浏览器书签,一张参考图留在相册,几行想到的话写进聊天记录。等真正需要这些材料时,往往只记得“以前保存过”。Karakeep 可以把链接、图片和笔记集中收集,配合标签、列表和搜索整理素材。

这次先部署不接外部模型的收藏库。自动标签属于可选能力,没有 API Key 也能使用基本收藏功能。启用模型、内容抓取或截图以前,应知道哪些材料会交给哪些服务处理,不能把“自建网页入口”理解成所有功能都会在浏览器里离线完成。

三个服务不要省掉其中一个

官方 Docker 配置包含网页应用、用于抓取的 Chrome 和 Meilisearch。应用保存收藏与附件,Chrome 参与网页处理,Meilisearch 提供搜索索引。网页能够登录,只证明入口正常,不能证明抓取与搜索都接通。

这三个服务的镜像和配置应来自同一份当前部署模板。不要把旧版 Hoarder 教程里的镜像名、浏览器地址和搜索版本拼在一起。Karakeep 曾更名,旧材料有参考价值,但升级路径和当前参数需要按正式文档核对。

服务器准备好 Docker Engine、Compose 插件和宿主机 Caddy,域名 keep.example.com 指向 VPS。考虑收藏图片的容量,并给搜索索引和网页抓取留内存。没有必要给初次试用承诺最低配置能容纳多少收藏,先用小批内容观察任务队列和资源使用。

mkdir -p /opt/karakeep/data /opt/karakeep/meili-data
cd /opt/karakeep
umask 077
openssl rand -hex 32
openssl rand -hex 32

创建 .env,两个随机值分别作为会话密钥和搜索主密钥,不使用公开示例。初始化先通过 SSH 转发,本机访问地址为 http://localhost:13000;正式入口接好后改回域名。

KARAKEEP_VERSION=release
NEXTAUTH_SECRET=your-generated-session-secret
MEILI_MASTER_KEY=your-generated-search-secret
NEXTAUTH_URL=http://localhost:13000
chmod 600 .env

按当前模板连接应用、浏览器和搜索

保存为 compose.yaml。以下采用研究时官方模板中的 Chrome 镜像与 Meilisearch 版本,应用和搜索都加载 .env。搜索和 Chrome 不发布宿主机端口,调试接口不应直接暴露到公网。

services:
  web:
    image: ghcr.io/karakeep-app/karakeep:${KARAKEEP_VERSION:-release}
    restart: unless-stopped
    ports:
      - "127.0.0.1:3000:3000"
    env_file: .env
    volumes:
      - ./data:/data
    environment:
      DATA_DIR: /data
      MEILI_ADDR: http://meilisearch:7700
      BROWSER_WEB_URL: http://chrome:9222
  chrome:
    image: ghcr.io/karakeep-app/karakeep-chrome:release
    restart: unless-stopped
    init: true
    command:
      - --disable-gpu
      - --disable-dev-shm-usage
      - --hide-scrollbars
      - --disable-blink-features=AutomationControlled
      - --window-size=1440,900
  meilisearch:
    image: getmeili/meilisearch:v1.41.0
    restart: unless-stopped
    env_file: .env
    environment:
      MEILI_NO_ANALYTICS: "true"
    volumes:
      - ./meili-data:/meili_data

DATA_DIR 保持容器内 /data,要改宿主机存储位置时改冒号左边的路径。浏览器和搜索地址使用 Compose 服务名,不能写宿主机回环地址。首次部署后记录三个镜像的摘要,固定经过核对的版本,避免应用更新而依赖组件未按要求更新。

docker compose config --quiet
docker compose pull
docker compose up -d
docker compose ps
docker compose logs --tail=100 web chrome meilisearch

这里使用 --quiet,避免展开环境变量时把密钥写进日志截图。应用首次启动会初始化数据;如果没有成功,先看报错来自应用、搜索认证还是 Chrome 连接。重复启动不能解决错误密钥或写入权限。

收藏入口先给自己使用

在自己的电脑执行 SSH 转发,打开本机 13000 端口,创建账号并保存一条公开链接。初始化阶段应用地址与 .env 中的 NEXTAUTH_URL 一致。

ssh -N -L 13000:127.0.0.1:3000 [email protected]

接域名前把 NEXTAUTH_URL 改为 https://keep.example.com,重新运行 docker compose up -d。Caddy 在宿主机时采用下面的站点段,验证配置后重载;若代理在容器中,改用共享网络里的 web:3000。

keep.example.com {
    reverse_proxy 127.0.0.1:3000
}

账号建立后,在 .env 中加入 DISABLE_SIGNUPS=true,运行 docker compose up -d,再用未登录窗口验证注册已经关闭。私人收藏可以限制在 VPN 中,给自己的浏览器与手机访问即可。用户之间的私有内容、分享链接和公开列表要分别检查,不能只因为登录页存在就判断所有收藏都被保护。

浏览器扩展和移动客户端填写正式地址。为每个集成分别管理访问凭据,设备不用时撤销对应凭据。临时 IP 与域名来回切换,可能让客户端指向两个不同入口,排障时先确认保存到了哪个实例和账号。

试用时保存三种材料

先保存一篇公开文章、一张无敏感内容的图片,再写一条短笔记。对照原页面检查标题、正文和图片;网页加入收藏之后,抓取任务可能还未结束,列表里出现一个卡片不代表已经保存完整正文。

图片写一段用途说明,例如“首页布局参考,想保留导航间距”。只堆几百张没有说明的截图,全文搜索也难以知道你当时关注什么。短笔记适合记录素材用途或待核实的问题,正式项目结论仍需要保留来源与时间。

标签先按稳定的主题分类,不把每篇文章标题变成一个标签。列表可以按项目组织,例如“迁移准备”“设计参考”,把完成的项目移出常用入口。项目结束以后留下有复用价值的材料,删掉明显失败或重复的收藏,能减少下次搜索时的干扰。

测试搜索时,选正文中出现而标题中没有的词,检查结果能否找回文章;再搜索一条笔记里的词。标题搜索正常、正文搜索不正常,可能是抓取尚未完成或索引没有更新,需要分别检查任务和搜索日志。

自动标签和截图按需开启

基础功能跑通以后再考虑自动标签。外部模型服务会按照所启用功能处理相关内容,需要费用与凭据;本地模型也需要额外的服务资源。不要把默认示例里的模型 Key 保留下来,更不要把私人收藏导入以后才决定是否允许外部处理。

网页截图和完整归档也应先用几条公开网页验证。登录页面、动态网站、反爬限制可能让抓取结果缺内容或只剩验证页。改抓取参数时保留当前可用配置,不要直接关闭所有检查;收藏工具不能保证完整复现任何网页。

服务器负责请求用户提交的地址,私人实例应限制用户范围。只允许你自己保存内容,比把入口开放给陌生人更容易控制抓取目标和资源消耗。收藏第三方网页时也要尊重访问与使用条件,不把工具用于绕过权限。

从任务状态判断故障

网页返回 502,先从宿主机访问 3000 端口,再查代理。界面正常但所有抓取失败,看 Chrome 是否启动、服务名是否正确和服务器到目标站点的网络。只有某个网站失败,保留样本,先判断页面或目标站点的限制,不要立即迁移整个实例。

搜索报错重点看 Meilisearch 日志与主密钥。修改 .env 后要重建相关容器,仅重启进程不会更新旧的容器环境。Meilisearch 版本迁移有自己的流程,不能把数据库目录原样交给任意新版本就假定成功。

磁盘紧张时,先统计 data 和 meili-data 的占用,区分附件与索引。不要把删除搜索目录当成通用清理命令;即便理论上能重建,也要先确认当前版本提供的重建方式、时间和完整数据是否还在。

备份应用数据与索引,记录版本组合

小规模实例可以停止三个服务后打包完整目录。这样备份处于同一时点,避免应用正在写入而索引和数据库分别复制。执行前确认空间够用,失败也要恢复容器运行。

cd /opt/karakeep
mkdir -p /opt/backups
docker compose stop
tar -czf "/opt/backups/karakeep-$(date +%F-%H%M).tgz" compose.yaml .env data meili-data
docker compose start

将备份复制到另一处存储,保护其中的账号、附件和密钥。恢复时采用对应镜像,在独立目录与不同端口启动,调整测试 NEXTAUTH_URL,暂时不接外部模型。检查链接、图片、笔记、标签与正文搜索,再判断是否完成恢复。

迁移以后重新核对浏览器扩展和手机入口,确认新保存的材料出现在同一库里。先保持少量标签和清楚的用途说明,这个收藏库才会成为能找回材料的地方,而不是又一个积满未读链接的列表。