把 Cumora 搬进懒猫微服:LightOS 天然适合 BYOA
最近看到开源项目 Cumora:它提供聊天、Agent、任务看板和日历,但真正吸引我的是 BYOA(Bring Your Own Agent)模式。服务端只负责协作和调度,Agent 则运行在自己的机器上,继续使用本地的 Codex 或 Claude。
这和懒猫微服的 LightOS 几乎是天然组合:LPK 承载稳定的 Web 与数据层,LightOS 承载需要工作目录、登录态和长期运行能力的 Agent。
这篇记录一次完整的移植和实测过程。
先划清边界
Cumora 有两条 Agent 运行路线:
- Cloud Managed:服务端动态创建 Kubernetes Pod。
- BYOA:用户自己的 Computer 运行
cumora agent computer。
第一条依赖 Kubernetes、PVC、FUSE、设备插件和较高容器权限,并不适合直接塞进普通 LPK。我的目标因此很明确:只做 BYOA 版,不移植 Cloud Agent。
最终架构如下:
浏览器
│ Lazycat SSO
▼
Cumora LPK
├─ React SPA + Express API + WebSocket
├─ PostgreSQL(持久化)
├─ Redis AOF(消息与在线状态)
└─ uploads(本地附件)
▲
│ .lzcapp 内网 + SSE
│
LightOS: teec-dev
└─ cumora agent computer
├─ Codex CLI
└─ Claude CLI
这样做的好处是,模型登录态、代码仓库、工作目录和 Agent 记忆都留在 LightOS;Cumora LPK 不需要拿到模型 API Key,也不需要创建高权限 Pod。
LPK 里放了什么
测试包拆成三个服务:
cumora:Node.js 服务,同时提供 SPA、API 和 WebSocket。postgres:保存用户、对话、Agent、任务和配置。redis:负责广播、Presence 和唤醒队列,启用 AOF。
持久化目录分别绑定到:
/lzcapp/var/postgres
/lzcapp/var/redis
/lzcapp/var/uploads
登录也做了懒猫适配。浏览器经过懒猫应用入口后,Cumora 使用可信的 X-HC-User-ID 换取自己的 Session,因此打开页面即可免密登录。API 没有加入 public_path,BYOA daemon 走内网服务地址,并在配对后使用自己的设备 Token。
此外,我增加了 CUMORA_BYOA_ONLY=true 硬开关。即使以后误改套餐或 Agent 配置,调度器也会在调用 kubectl 前停止,不会意外进入 Cloud Agent 路径。
真正花时间的不是打包
源码能构建,不等于应用能稳定启动。这次主要遇到三个问题。
1. Docker Hub 镜像拉取卡住
Cumora 本体镜像已经打进 LPK,但 PostgreSQL 和 Redis 最初直接引用 Docker Hub。安装成功后,应用在首次启动阶段一直等待外部镜像。
解决方式是改用懒猫 Registry 中已经存在的固定镜像。这样既避开外网拉取,也让版本可重复。
2. PostgreSQL 初始化与时区
首次尝试使用的 PostgreSQL 镜像把系统时区写成了 PRC,后续启动时配置校验失败。最终换成懒猫 Registry 的 PostgreSQL 17 Alpine 镜像,并显式设置:
TZ=Asia/Shanghai
测试期间产生的失败初始化目录也先整体移走,再用干净数据目录重新初始化,避免拿半成品数据库继续试。
3. 服务启动存在竞争
depends_on 只保证容器启动顺序,不保证 PostgreSQL 已经能接受连接。实际日志先后出现过:
getaddrinfo EAI_AGAIN postgres
connect ECONNREFUSED postgres:5432
我扩展了数据库启动重试,把 DNS 暂时失败和连接拒绝都视为可恢复错误,使用指数退避重试。这样整套应用重启时,Cumora 会等待数据库就绪,而不是直接退出。
LightOS 如何接入 Cumora
这是最关键的一段。浏览器访问的是外部地址,但 LightOS daemon 应优先使用懒猫应用间的 .lzcapp 内网地址。
内网服务地址规则是:
http://<service>.<package-id>.lzcapp:<port>
本次应用的三个值是:
service = cumora
package-id = cloud.lazycat.app.cumora.byoa.poc
port = 5181
所以完整服务端地址为:
http://cumora.cloud.lazycat.app.cumora.byoa.poc.lzcapp:5181
先在 Cumora 页面进入 Computer 管理,点击添加 Computer,取得配对 Token。然后在 LightOS 终端执行:
npx cumora@latest agent computer \
--pair PAIR_TOKEN_HERE \
--server http://cumora.cloud.lazycat.app.cumora.byoa.poc.lzcapp:5181 \
--engine codex
把 PAIR_TOKEN_HERE 替换为页面生成的 Token。这里最容易漏掉的就是 --server:不指定时,CLI 会使用 Cumora 默认服务端;在自托管环境里必须明确指向自己的 .lzcapp 地址。
配对成功后,建议把 daemon 安装成 LightOS 的用户服务:
npx cumora@latest agent computer \
--install-service \
--server http://cumora.cloud.lazycat.app.cumora.byoa.poc.lzcapp:5181
检查状态与日志:
npx cumora@latest agent computer --status
journalctl --user -u cumora -f
需要手动重启时:
systemctl --user restart cumora
LightOS 已开启用户服务常驻后,即使终端关闭,daemon 仍会继续运行;实例或服务重启后也会自动恢复。
我做了哪些真实验证
这次没有停在“页面能打开”。完整链路验证是:
teec-dev配对为 Cumora Computer。- Atlas、Bram、Iris、Nova 四个 Agent 建立 SSE wake stream。
- 在页面给 Atlas 发送消息。
- Atlas 在 LightOS 上唤醒本地 Codex。
- Codex 通过 Cumora CLI 回复:“Cumora BYOA 链路正常”。
随后我分别重启了 cumora 用户服务和整套 LPK。Computer 自动恢复在线,四条 SSE 重新连接,之前的消息仍在,证明 systemd 常驻、PostgreSQL 持久化和内网连接都生效。
结论
BYOA 的核心不是“把 Agent 放到另一台机器”,而是把职责拆对:
- LPK 负责稳定、可访问、可持久化的协作服务。
- LightOS 负责有状态、可操作本地文件、能长期运行的 Agent。
.lzcapp负责盒内直连,避免为 daemon 额外开放公网 API。
这套组合保留了本地 Agent 的能力和隐私边界,又获得了一个随时可访问的协作界面。至少对个人使用来说,LightOS 的确是很合适的 BYOA Computer。