docs: add project README and deployment guide

Document how to start, configure, and deploy the local Kanban app
including auth, GPU hosts, Gitea integration, quota checking, and
agent session management.
This commit is contained in:
2026-05-15 11:14:27 +08:00
parent 72289d2c75
commit 677d41074b

141
README.md Normal file
View File

@@ -0,0 +1,141 @@
# Local Kanban
本地 Web 看板,用来汇总 SSH 可访问开发机的 GPU 使用情况、IPADS API 额度、本地 Gitea 项目,并从选定 project/branch 准备 workspace 后启动 agent。
## 启动
```bash
npm start
```
默认地址是 `http://127.0.0.1:5180`,生产访问通常走 `https://gahow-pc.ipads-lab.se.sjtu.edu.cn:8443/` 的本地 Nginx 反代。
首次启动会生成访问 token并保存到 `~/.config/local-kanban/state.json`。登录页需要输入这个 token
```bash
jq -r .authToken ~/.config/local-kanban/state.json
```
也可以用固定环境变量覆盖:
```bash
KANBAN_AUTH_TOKEN='long-random-token' npm start
```
如果通过 HTTPS 反代访问,可设置 `KANBAN_AUTH_SECURE_COOKIE=1` 让浏览器只在 HTTPS 连接发送 cookie。纯 HTTP 暴露在局域网时token 登录能阻止未授权用户直接访问服务,但链路本身不能抵御同网段抓包;需要“强隔离”时应配合 HTTPS、VPN 或 SSH tunnel。
HTTPS 反代推荐让 Node 只监听本机:
```bash
KANBAN_HOST=127.0.0.1 \
KANBAN_PORT=5180 \
KANBAN_AUTH_SECURE_COOKIE=1 \
KANBAN_REQUIRE_HTTPS=1 \
npm start
```
Nginx 示例在 `deploy/nginx.local-kanban.conf`。当前设计是:
- `https://gahow-pc.ipads-lab.se.sjtu.edu.cn/` 是入口首页
- 每个服务仍然保留自己的端口,例如 Kanban 是 `https://gahow-pc.ipads-lab.se.sjtu.edu.cn:8443/`
- 入口首页展示 Gitea、Kanban、Stock Agent 三个常用服务
- 后端 API 链接默认折叠,需要时展开
系统 Nginx 负责:
- TLS 终止
- 在 443 提供静态入口首页
- 在 3443 反代 Gitea 的 3300
- 在 5443 反代 Stock Agent 前端的 5174并把 `/api` 转发到 8787
- 在 8788 直接反代 Stock Agent API 的 8787
- 默认不监听 80避免和现有本地服务冲突
没有 sudo 时,可以使用当前仓库里的用户级 Nginx 配置监听 8443详见 `deploy/README.md`
如果需要持久运行 Node app 和用户级 Nginx可以安装用户级 systemd 服务:
```bash
./scripts/install-user-systemd.sh
```
## 配置
可以用环境变量快速配置:
```bash
KANBAN_GPU_HOSTS=dash0,dash1 \
KANBAN_GITEA_BASE_URL="http://gahow-pc.ipads-lab.se.sjtu.edu.cn:3300" \
npm start
```
也可以创建 `~/.config/local-kanban/config.json`
```json
{
"gpuHosts": ["dash0", "dash1"],
"gitea": {
"baseUrl": "http://gahow-pc.ipads-lab.se.sjtu.edu.cn:3300",
"tokenEnv": "GITEA_TOKEN"
},
"workspaceRoot": "/home/gahow/.local/share/local-kanban/workspaces",
"authSecureCookie": true,
"requireHttps": true,
"quotaSources": [
{
"id": "ipads",
"label": "IPADS API",
"type": "command",
"command": "bash",
"args": ["-lc", "curl -sS -H \"Authorization: Bearer $IPADS_API_KEY\" http://tianx.ipads-lab.se.sjtu.edu.cn:8319/v1/usage | jq '{remaining, usage}'"],
"timeoutMs": 15000
}
],
"agentProfiles": [
{
"id": "codex-full",
"label": "Codex Full Permission",
"command": "codex",
"args": [
"--dangerously-bypass-approvals-and-sandbox",
"exec",
"--sandbox",
"danger-full-access",
"--cd",
"{workspace_path}"
]
}
]
}
```
GPU 机器列表可以在 Web 页面里编辑保存,保存位置是 `~/.config/local-kanban/state.json`。默认只读取当前项目目录的 `/home/gahow/projects/kanban/.env`。需要的 key 可以参考 `.env.example`
```bash
GITEA_TOKEN=replace-with-your-gitea-token
IPADS_API_KEY=replace-with-your-ipads-api-key
```
也可以用逗号分隔的 `KANBAN_ENV_FILE` 指向其他 env 文件。
## API
- `GET /api/gpus`: 查询 `ssh <host> nvidia-smi --query-gpu=index,name,memory.used,memory.total,utilization.gpu --format=csv,noheader,nounits`
- `PUT /api/settings/gpu-hosts`: 保存需要监控的 GPU 机器列表
- `POST /api/auth/login`: 使用本地 token 登录并设置 HttpOnly cookie
- `POST /api/auth/logout`: 清除登录 cookie
- `GET /api/quotas`: 执行默认的 IPADS API 额度命令
- `GET /api/repos`: 从 Gitea `/user/repos` 读取仓库
- `GET /api/branches?repo=owner/name`: 从 Gitea 读取 branch list
- `GET /api/agent-profiles`: 返回可选 AI 配置
- `POST /api/tasks`: 准备选定 project/branch 的 workspace 后启动 agent 命令
- `GET /api/dashboard`: 聚合以上数据,供 Web 和后续 iOS 复用
## Agent Session 历史
任务历史会保存到 `~/.config/local-kanban/state.json`。每次 Codex 启动后,服务会从输出中提取 `session id` 并记录到对应的 project/branch。之后在同一个 project/branch 下,可以在 Web UI 的 “历史 Session” 下拉框里选择之前的任务,点击 “继续 Session” 发送新指令。
继续会话使用:
```bash
codex --dangerously-bypass-approvals-and-sandbox exec --sandbox danger-full-access --cd <workspace> resume <session_id> <prompt>
```