過去半年我換過三套專案管理工具,Jira 因為欄位太多被 PM 設成迷宮、Notion 拿來追 sprint 又卡得跟泥巴一樣、Linear 雖然舒服但要把資料丟到別人雲端始終讓人有點不安。最後在 GitHub Trending 看到 Kaneo,定位很單純:「All you need. Nothing you don't.」一句話打中我,於是花了一個週末把它架在自己機器上跑。
這篇是部署紀錄,順便整理一下實際用過後對它與其他主流工具的對比。Kaneo 的故事很典型 — 一個受夠 Jira 的工程師決定自己寫一個。技術選型也夠純粹:TypeScript 全端、Hono 寫 API、React 寫前端、PostgreSQL 存資料、MIT License。不繞遠路。
對於小型團隊或個人 side project,找一套會「消失在工作流裡」的工具,比找一套功能滿載的工具有用得多。下面分享完整的 Docker Compose 部署流程、踩過的幾個坑,以及為什麼最後決定把它放上正式環境。

圖片來源:Kaneo 官方 README
一、為什麼選擇極簡專案管理
Jira 是業界標配,但它的設計哲學是「滿足所有可能的工作流」,於是出現了 Epic、Story、Sub-task、Custom Field、Workflow、Permission Scheme 一整串無止境的設定樹。對大型企業合理,對 5 人團隊根本是災難。光是「新增一個 issue type」就要 admin 開後台改 scheme,再 link 到 project,整個流程要按七八下,工程師早就放棄不用了。
Notion 走的是另一條路:把專案管理當成資料庫的延伸,用法靈活,但缺點就是太靈活 — 每個團隊都要花時間建模板、決定 view、約定欄位語意。半年後就會發現有三個半成品的 sprint board,沒有人想再 maintain。Notion 的另一個痛點是反應速度,每次切 view 都要等個半秒到一秒,用久了會覺得思路一直被打斷。
我的需求其實只有四件事:
- 看得見的 Kanban 欄位(To Do / In Progress / Done)
- Task 可以指派、設 due date、加 label
- 跟 Git workflow 串得起來
- 資料完全在自己手上
Kaneo 把這四件事做到位,其他能砍的全部砍掉。沒有 Sprint Velocity Chart、沒有 Burndown、沒有 OKR 模組、沒有甘特圖。一進去就是一塊乾淨的看板,這就是它的賣點。
二、Kaneo 的設計哲學
作者 Andrej 在官網上講過一句話讓我印象很深:「最好的工具是隱形的(the best tools are invisible)」。這句話翻成工程師語言大概是 — 工具不該打斷你的 flow,不該每天逼你看 12 種通知,不該讓你花 30 分鐘搞懂怎麼 archive 一個 task。
從產品的幾個決策可以看出這個方向:
- 單一資料源:Board view 與 List view 共用同一份資料,切換不會出現「咦剛剛那個 task 跑去哪了」的狀況
- Label 取代複雜層級:不搞 Epic/Story/Subtask 那種多層樹狀結構,用 label 串接跨專案議題
- Privacy-first:自架版本不上報任何 telemetry,雲端版的 analytics 也降到最低
- Native GitHub / Gitea 整合:直接把 issue 同步進來,Pull Request 狀態回寫到 task
這跟 Linear 的哲學很像,但 Linear 沒有自架版。對在意資料主權的團隊(受 GDPR、個資法規範、或單純不想付月費),Kaneo 是少數既極簡又能完全 self-host 的選擇。
技術選型也呼應這個極簡哲學。後端用 Hono 而不是 Express 或 NestJS,意味著作者在意冷啟動速度與最終 bundle 大小。前端是 React + TypeScript 但沒有疊任何重的 state management,以實際 bundle 體積估,整套 web 容器 image 不到 100MB。資料庫選 PostgreSQL 而不是 SQLite,是為了讓多人並發寫入更穩,但又沒上 Redis 與 message queue,看得出取捨清楚 — 不為了「未來可能用到」而堆架構。
三、Docker 部署
官方主推 Docker Compose 起服務,三個容器:PostgreSQL、API、Web。整套部署不到 10 分鐘。
3.1 docker-compose.yml 設定
先準備好資料目錄與 compose 檔。我習慣放在 /data/kaneo 底下,邏輯清楚:
mkdir -p /data/kaneo/data
mkdir -p /data/postgresql/data
chmod 777 /data/kaneo /data/postgresql
cd /data/kaneo
vi docker-compose.yaml
完整 compose 檔:
services:
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: kaneo
POSTGRES_USER: kaneo_user
POSTGRES_PASSWORD: ChangeMe_Strong_Password
volumes:
- /data/postgresql/data:/var/lib/postgresql/data
restart: unless-stopped
backend:
image: ghcr.io/usekaneo/api:latest
environment:
JWT_ACCESS: "REPLACE_WITH_64_CHAR_RANDOM_STRING"
DATABASE_URL: "postgresql://kaneo_user:ChangeMe_Strong_Password@postgres:5432/kaneo"
CORS_ENABLED: "true"
CORS_ORIGINS: "http://your-server-ip:5173,http://127.0.0.1:5173"
CORS_METHODS: "GET,POST,PUT,DELETE,OPTIONS"
CORS_HEADERS: "*"
CORS_CREDENTIALS: "true"
ports:
- "1337:1337"
volumes:
- /data/kaneo/data:/app/apps/api/data
depends_on:
- postgres
restart: unless-stopped
frontend:
image: ghcr.io/usekaneo/web:latest
environment:
KANEO_API_URL: "http://your-server-ip:1337"
ports:
- "5173:5173"
depends_on:
- backend
restart: unless-stopped
啟動:
docker compose pull
docker compose up -d
docker compose ps
第一次啟動 PostgreSQL 會自動跑 migration,看到三個容器都是 Up 就可以打開 http://server-ip:5173。如果 docker compose ps 看到 backend 反覆重啟,先看 docker compose logs backend,九成是 DATABASE_URL 連不上或 JWT_ACCESS 沒設。
3.2 必要的環境變數
JWT_ACCESS 是後端簽 JWT 的 secret,千萬別用範例值。產生方式:
openssl rand -hex 32
或者:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
DATABASE_URL 連線字串注意如果密碼裡有 @ : / 這些特殊字元,要做 URL encode(或者乾脆別用),否則 Hono 啟動會報 parse 錯誤。生產環境建議把密碼放到 .env 檔搭配 compose 的 env_file 引用,避免直接寫死在 yaml 被 commit 進版控。
CORS_ORIGINS 這個欄位很容易踩雷。前端 Web 容器跑在 5173,後端 API 跑在 1337,瀏覽器從 Web 發起的 request 來源是 http://server-ip:5173,所以這個來源必須加進白名單。如果之後接了反向代理換成 https://kaneo.example.com,記得連這個 domain 一起加進來,不然 preflight 直接被擋。我第一次架的時候漏了這個,登入按下去 console 整片紅,找了 20 分鐘才發現是這個欄位。
KANEO_API_URL 是前端打 API 的位置,這個值會被瀏覽器看到,所以不能寫 docker 內部 hostname(http://backend:1337 會壞),要寫使用者瀏覽器能解析的 URL。同樣,如果之後接了反向代理換 HTTPS domain,這裡也要一起改。
3.3 反向代理與 HTTPS
對外暴露 5173 跟 1337 兩個 port 不太優雅,用 Caddy 一份 Caddyfile 就能搞定 HTTPS:
kaneo.example.com {
reverse_proxy localhost:5173
}
api.kaneo.example.com {
reverse_proxy localhost:1337
}
這時候 compose 裡面要改:
backend:
environment:
CORS_ORIGINS: "https://kaneo.example.com"
frontend:
environment:
KANEO_API_URL: "https://api.kaneo.example.com"
Caddy 第一次啟動會自動跟 Let's Encrypt 拿憑證。如果用 Nginx 或 Traefik 路徑也類似,重點是 API 跟 Web 各對一個子域,CORS 與 KANEO_API_URL 同步調整。
部署流程整體像這樣:
flowchart LR
User[使用者瀏覽器] -->|HTTPS| Caddy[Caddy 反向代理]
Caddy -->|kaneo.example.com| Web[Frontend :5173]
Caddy -->|api.kaneo.example.com| API[Backend :1337]
Web -.->|fetch API| Caddy
API --> DB[(PostgreSQL)]
DB -.->|volume| Disk[/data/postgresql/data]
API -.->|volume| Files[/data/kaneo/data]
四、核心功能
4.1 Workspace 與 Project
Kaneo 的概念層級很扁:Workspace → Project → Task。Workspace 通常對應一個團隊或一個產品線,底下開多個 Project(例如「前端」「後端」「資料平台」),每個 Project 自己一塊 Kanban。
第一次登入會走註冊流程(自架版預設沒有開 social login,要手動接 GitHub OAuth),登入後就是 dashboard 引導你 Create Workspace,再 Create Project。介面非常直覺,沒有那種「我得先讀 30 頁文件才能開第一個 project」的挫折感。建立 Workspace 之後可以直接邀請成員,邀請邏輯走 email 邀請或產生 invite link,跟 Slack 邀請流程差不多。
4.2 Task 管理
Task 有幾個基本屬性:title、description(Markdown)、assignee、due date、priority、labels、status。Status 預設是 To Do / In Progress / In Review / Done,可以自己改欄位名稱與顏色。
我比較喜歡的幾個小細節:
- 拖拉順暢:跟 Linear 一樣的 60fps 拖拉感,沒有 Jira 那種「拖完還要等 1 秒重新整理」
- List 跟 Board view 切換無縫:同一份資料兩種呈現
- Markdown 描述:可以直接貼程式碼 fenced block,不會被吃掉
- 快捷鍵:
C開新 task、/搜尋、Esc關閉,符合鍵盤族肌肉記憶
少了什麼?自訂欄位(Custom Field)、Sprint 概念、時間估算(estimate)、子任務階層 — 這些都沒有。對輕量團隊夠用,對需要做容量規劃的就要評估。
我自己的折衷做法:用 label 模擬 sprint。例如 sprint-2026w17 這種命名,週週開新 label,過期 label 用顏色淡化。雖然原始,但實作簡單,搜尋與篩選效率反而比 Jira 那套 sprint board 更直覺。同樣用 label 也可以做粗略的優先級分類(p0、p1、p2),不必依賴專屬欄位。
4.3 多人協作與權限
權限模型簡單:Workspace 層級分 Owner / Member,Project 層級可以指派參與者。沒有 Jira 那種 Permission Scheme 八層巢狀設定,但也意味著比較細的場景(例如「外部廠商只能看不能改」)做不到。對 5 ~ 30 人左右的團隊夠用,再大就要評估自己 fork 一份補功能。
GitHub / Gitea 整合是亮點。設定好之後 issue 可以雙向同步,PR merge 自動把對應 task 移到 Done。對於本身就用 Git issue tracker 的團隊,可以把 Kaneo 純粹當成 visual layer,不必雙重維護。設定方式是在 Workspace 層級接 GitHub App,授權後選擇要同步的 repo,同步策略可以選 issue → task 單向、或 task ↔ issue 雙向。
五、實測心得
我把它丟在一台 1 vCPU / 2GB RAM 的小 VM 上跑,三個容器加起來常駐記憶體大約 350MB,PostgreSQL 占大頭。Idle 時 CPU 趨近於零。實際開了 5 個 project、約 200 條 task,操作沒有任何延遲。
幾個觀察:
- 冷啟動快:API 容器從啟動到 ready 大約 3 秒,Web 容器 1 秒
- 資料庫 schema 簡潔:用
psql進去看大約十幾張表,沒有 Jira 那種上百張的恐怖場面 - 升級無痛:
docker compose pull && docker compose up -d,PostgreSQL volume 不動,目前沒踩過 migration 雷 - 備份直接:
pg_dump+/data/kaneo/data打包就完事
備份腳本可以寫成這樣,丟去 cron 每天跑:
#!/usr/bin/env bash
set -euo pipefail
TS=$(date +%Y%m%d-%H%M%S)
BACKUP_DIR=/data/backups/kaneo
mkdir -p "$BACKUP_DIR"
docker exec kaneo-postgres-1 pg_dump -U kaneo_user kaneo \
| gzip > "$BACKUP_DIR/kaneo-$TS.sql.gz"
tar czf "$BACKUP_DIR/kaneo-data-$TS.tar.gz" /data/kaneo/data
# 保留 30 天
find "$BACKUP_DIR" -mtime +30 -delete
唯一的小問題是中文搜尋 — 預設 PostgreSQL 沒裝中文分詞,搜尋中文 task title 是用 LIKE,量大會慢。如果團隊 task 大量用中文寫,可以考慮把 PostgreSQL 換成裝了 zhparser 或 pg_jieba 的 image。我自己用英文 + 少量中文混寫,目前沒遇到效能瓶頸。
六、vs. Jira / Linear / Trello / Notion
實際比較幾個主流工具的差異:
| 維度 | Kaneo | Jira | Linear | Trello | Notion |
|---|---|---|---|---|---|
| 自架 | 可(Docker) | 可(Data Center 收費高) | 不可 | 不可 | 不可 |
| 開源 | MIT | 否 | 否 | 否 | 否 |
| 學習曲線 | 極低 | 高 | 低 | 極低 | 中 |
| 速度 | 快 | 慢 | 極快 | 快 | 中 |
| 自訂欄位 | 無 | 強 | 中 | 弱 | 強 |
| Git 整合 | 原生 | Plugin | 原生 | Plugin | 弱 |
| 免費版 | 全功能 | 有限 | 個人/小團隊 | 基本看板 | 基本 |
| 適合規模 | 小到中 | 大企業 | 中型新創 | 個人/小組 | 文件導向團隊 |
幾個觀點:
Linear 是 Kaneo 最像的對手,UX 也是業界標竿,但 Linear 的軟肋是不能自架。對受合規規範或單純省錢的團隊,Kaneo 補上這個缺口。功能廣度 Linear 還是領先,例如 Cycles、Initiatives、Triage 這些對中型新創很有用,但對追求純粹的小團隊反而是雜訊。
Jira 不是錯誤的選擇,只是錯誤的場景。如果團隊 50 人以上、有正式 Scrum Master、需要做 quarterly planning 跟 capacity 計算,Jira 還是繞不開。但 5 人團隊用 Jira 90% 是 PM 在浪費自己時間。
Trello 跟 Kaneo 看起來很像(都是極簡看板),差別在 Kaneo 多了自架、Git 整合、多 project 結構。Trello 適合非技術團隊(行銷、編輯),Kaneo 偏向技術團隊。Trello 的 Power-Up 機制可以加擴充,但很多 Power-Up 是要錢的,加一加價格不見得比 Linear 便宜。
Notion 是不同物種。它是文件 + 資料庫,硬要當專案管理用會慢、會卡、會在開 sprint 時讓人想哭。Notion 留給寫文件、做知識庫、寫 PRD,Kaneo 留給追任務。實務上我會把 PRD 跟 RFC 放 Notion,task 拆解後 link 進 Kaneo 的 description,兩邊各司其職。
七、適合與不適合的場景
適合:
- 5 ~ 30 人技術團隊,主要追 issue 與 sprint
- 對資料主權有要求(金融、醫療、政府專案)
- 已經用 GitHub / Gitea 管程式碼,想要視覺化的 task layer
- 個人 side project 或 indie hacker,不想付 SaaS 訂閱
- 受夠 Jira 想換但不想被另一個 SaaS 綁死
不適合:
- 50 人以上、有正式 PMO 流程的企業
- 需要 portfolio level 規劃(多 project 容量、跨團隊路線圖)
- 高度依賴自訂欄位與 workflow rule 的團隊
- 非技術人為主的團隊(Trello 或 Asana 更友善)
- 需要 enterprise SSO 與 audit log 的環境(Kaneo 還在補這塊)
八、小結
Kaneo 不是要打敗 Jira,它瞄準的根本是另一群人 — 那些不想被工具綁架的小團隊與工程師。它的賣點不是功能多,而是功能少且把那些功能做到絕對好用。
部署很單純,三個 Docker 容器、幾個環境變數、一份 Caddyfile 反代。資料完全在自己掌握中,要備份直接 pg_dump。對於受夠 Jira 又不想付 Linear 月費、且重視 self-host 的團隊,這套工具值得花 30 分鐘試試。
下一步我打算把它跟自架的 Gitea 串起來,讓 commit message 帶 task ID 自動關閉 issue,再把 Slack webhook 接過去做 daily standup 摘要。等踩完坑會再寫一篇接續。
參考資料
- 原始參考:【技术实战】开源极简项目管理 Kaneo 部署指南:基于 Docker 的私有化方案 — 网域极客(2026/04/14)
- Kaneo GitHub Repository:https://github.com/usekaneo/kaneo
- Kaneo 官網:https://kaneo.app/
- Kaneo 官方文件:https://kaneo.app/docs
- Docker Compose 文件:https://docs.docker.com/compose/
- Caddy 反向代理:https://caddyserver.com/docs/

發佈留言