Kaneo 自托管部署:Docker Compose 与实时协作架构

Kaneo 是一个采用 MIT License 的开源、自托管项目管理工具,核心场景是任务列表、看板和项目协作。它最近出现在 GitHub Trending 的第 3 位,仓库记录的日增 star 数为 778。Kaneo 用 pnpm monorepo 组织 API、Web 和文档站,官方 Compose 部署用一个应用容器连接 PostgreSQL,Redis 只在需要多实例实时广播时加入。

本文围绕自托管使用者会关心的路径展开:它由哪些组件组成,最小部署需要什么,实时同步如何扩展,GitHub 集成和 MCP 入口放在架构的什么位置,以及哪些地方需要在上线前认真评估。

先看仓库给出的系统边界

Kaneo 当前仓库的顶层结构是一个 pnpm monorepo,主要目录包括:

目录官方仓库中的职责
apps/apiHono/Node.js API 服务
apps/webReact、Vite、TanStack Router 前端
apps/docsNext.js 文档站
packages/email邮件相关工具
packages/libs共享库
packages/typescript-configTypeScript 配置共享
chartsKubernetes Helm Chart

后端使用 Hono、PostgreSQL、Drizzle ORM、Better Auth 和 Valibot。前端使用 React 19、TanStack Router、TanStack Query、Vite、Tailwind CSS v4、Zustand 和 Radix UI。仓库还把 OpenAPI 描述、CUID2 主键、数据库迁移和事件发布约束写进了开发说明。

这组技术选择说明 Kaneo 的重点在于维持一个可独立部署、可继续开发的产品骨架。API 按功能拆目录,控制器承载业务逻辑,输入通过 Valibot 校验;Web 端把数据请求、查询缓存和页面路由分开。对自托管用户来说,这种边界比宣传页上的功能列表更重要,因为它决定了后续排错和定制的成本。

Kaneo 官方 Dashboard 看板截图

最小生产部署需要两个服务

官方 compose.yml 的核心只有 postgreskaneo 两个服务。PostgreSQL 使用 postgres:16-alpine 镜像,数据写入名为 postgres_data 的持久化卷;Kaneo 使用 ghcr.io/usekaneo/kaneo:latest,对外暴露 5173 端口,并等待 PostgreSQL 健康检查通过后启动。

配置文件至少要明确以下变量:

dotenv
KANEO_CLIENT_URL=http://localhost:5173
POSTGRES_DB=kaneo
POSTGRES_USER=kaneo
POSTGRES_PASSWORD=change-this-password
AUTH_SECRET=generate-a-random-string-with-at-least-32-characters

这里有两个容易被忽略的细节。

第一,AUTH_SECRET 至少需要 32 个字符,官方示例建议用 openssl rand -hex 32 生成。自托管实例如果不设置它,应用启动时会生成随机密钥,重启后会话无法继续使用。生产环境应把它作为持久化配置管理,而不是每次启动临时生成。

第二,API 在 Compose 网络里访问数据库时使用服务名 postgres。如果把 API 直接跑在宿主机上,数据库地址要改成 localhost,或者显式填写 DATABASE_URL。官方环境配置文档特意区分了这两种运行方式,原因在于两种运行方式处于不同的网络命名空间,连接目标也随之变化。

启动命令是:

bash
cp .env.sample .env
# 编辑 .env,填写数据库密码和 AUTH_SECRET
docker compose up -d

部署后,Kaneo 容器的健康检查访问 http://127.0.0.1:5173/api/health。如果反向代理返回 502,先看容器健康状态和 PostgreSQL 日志,再检查 KANEO_CLIENT_URLKANEO_API_URL 与代理外部域名是否一致。

实时同步为什么预留了 Redis

官方环境文档把 Redis 描述为 WebSocket Pub/Sub 的可选组件。没有配置 Redis 时,Kaneo 使用进程内内存适配器,这适合单实例部署。配置 Redis 后,多个 API 实例可以通过 Pub/Sub 转发 WebSocket 广播。

这个设计可以用一个简化的事件路径表示:

text
浏览器 A 修改任务
        |
        v
   API 实例 1
        |
        +--> 写入 PostgreSQL
        |
        +--> 发布实时事件
                 |
        单实例:内存适配器
        多实例:Redis Pub/Sub
                 |
        +--------+--------+
        v                 v
   API 实例 1         API 实例 2
        |                 |
        v                 v
   浏览器 A           浏览器 B

单实例时,事件只需在当前进程内广播,依赖少、延迟路径短。多实例时,用户可能连接到不同 API 进程,必须有共享的消息通道,否则浏览器 B 看不到浏览器 A 的更新。Redis 在这里承担的是事件分发,不是任务数据的最终存储。任务、状态、标签和权限仍然由 PostgreSQL 保存。

官方文档列出了三种 Redis 部署模式:Standalone、Sentinel 和 Cluster,并规定了优先级:Cluster 高于 Sentinel,Sentinel 高于 Standalone。自托管小团队通常只需要 Standalone;只有在 API 横向扩容或已经维护高可用 Redis 基础设施时,才需要考虑 Sentinel 或 Cluster。把 Redis 放进单机 Compose 并不会自动带来高可用,它只增加了一个可用的共享广播通道。

GitHub 集成和 GitHub 登录是两件事

Kaneo 的环境变量把 GitHub 能力拆成了两组:

第一组是 GitHub OAuth,用于“使用 GitHub 登录”。变量是 GITHUB_OAUTH_CLIENT_IDGITHUB_OAUTH_CLIENT_SECRET,仓库还保留了旧变量名作为兼容回退。

第二组是 GitHub App,用于仓库同步和 Webhook。变量包括 GITHUB_APP_IDGITHUB_PRIVATE_KEYGITHUB_WEBHOOK_SECRET 和可选的 GITHUB_APP_NAME

两组配置对应不同的权限边界。OAuth 主要解决身份认证,GitHub App 解决应用访问仓库、接收事件和同步开发执行状态。把二者混成一个“GitHub 配置”会让排错方向出错:用户登录失败,应查 OAuth 回调和客户端密钥;Issue 或 Webhook 不同步,应查 GitHub App 的安装范围、私钥和回调签名。

这一拆分也让 Kaneo 更适合开发团队:产品任务和 GitHub Issue 可以放在同一套工作流里,身份系统与仓库集成各自独立配置。它不会自动解决项目管理中的流程问题,但可以减少产品计划和代码执行之间的重复录入。

MCP 入口适合什么工作

官方环境说明中提到 kaneo-clikaneo-mcp 这两个设备授权客户端 ID。仓库还提供了 DEVICE_AUTH_CLIENT_IDS 配置,用来覆盖默认允许的设备流客户端列表。

这说明 Kaneo 的自动化入口至少包括两类:命令行设备流,以及给模型或其他工具使用的 MCP 连接。实际使用时,MCP 更适合处理结构化、重复性的动作,例如读取某个项目的任务、创建一张待办卡片、更新状态或查询负责人。权限配置仍然应该由 Kaneo 的认证和授权系统控制,不能把 MCP 当成绕过权限的内部接口。

对 AI 工作流来说,项目管理系统最需要的并非一段自然语言摘要,而是可被可靠读写的任务实体:项目、状态、优先级、负责人、标签、截止日期和关联 Issue。MCP 如果围绕这些实体提供工具,模型才能把会议结论或代码变更转成可追踪的工作项。Kaneo 的 monorepo、API 校验和设备流配置,为这种接入提供了工程位置,但具体自动化效果仍取决于权限、字段设计和调用方的错误处理。

自托管前要检查的四个问题

1. 数据持久化是否完整

PostgreSQL 卷是必须保留的。只保存 Kaneo 容器而没有保存 postgres_data,重建容器后任务数据会丢失。备份策略也应围绕 PostgreSQL 数据库制定,而不是只备份 Compose 文件。

2. 反向代理是否保持同源配置

KANEO_CLIENT_URLKANEO_API_URL、CORS 和外部 HTTPS 域名需要互相匹配。官方文档建议生产环境使用 HTTPS,并把 CORS_ORIGINS 设置为明确的前端地址。前端能打开但登录失败,常见原因就是这组 URL 之间存在协议、域名或端口差异。

3. 单实例是否足够

单台服务器、少量协作者和内存 WebSocket 适配器可以保持部署简单。需要多 API 实例时,Redis 才有明确价值。扩容之前先确认数据库连接池、反向代理会话和 WebSocket 路由策略,否则多实例只会把一个问题拆成几个问题。

4. GitHub 权限是否按用途拆分

登录、Issue 同步和 Webhook 接收需要不同的 GitHub 配置。部署时只开启实际需要的能力,私钥和 Webhook 密钥放在密钥管理系统或受限的环境文件中,不要写入仓库。

这个项目适合哪些团队

Kaneo 更适合希望掌握数据和部署边界的小团队、个人开发者和内部工程团队。它的仓库提供了 Docker Compose 和 Helm 两条路径,前者适合快速上线,后者适合已经有 Kubernetes 运维体系的团队。MIT License 也降低了二次开发和内部定制的门槛。

它的代价同样清晰:自托管意味着数据库备份、升级、域名、HTTPS、邮件服务和故障排查都由部署者负责。仓库的配置项已经覆盖 Redis、SMTP、SSO、GitHub App 和通知接收器,但每增加一项能力,就会增加一组密钥、网络和权限问题。部署前应先确定团队需要的最小功能,再逐项开启。

Kaneo 出现在 GitHub Trending 的价值,在于它把一个常见需求压缩成了可阅读的系统:React 前端、Hono API、PostgreSQL 数据、可选 Redis 广播、GitHub 集成和 MCP 入口各有边界。对准备自建项目管理系统的人来说,重点在于这套可以从单机 Compose 起步、再按协作规模增加基础设施的部署路径。

来源