logo
42
15
WeChat Login

✨ happy-cnb

一个容器,跑起 Happy 全家桶:用浏览器(桌面 / 移动端适配)远程控制容器里的 AI 编程 Agent

Docker Ready MIT License Platform Based on slopus/happy


这是什么

happy-cnb 基于开源项目 slopus/happy 二次开发,把原本需要分开部署的三件套打包进同一个 Docker 镜像,开箱即用:

组件说明
happy-server后端中继,提供 REST + Socket.io
happy-appWeb 控制台,仅分发 Web 端并适配移动端浏览器
happy CLI包裹 AI 编程 Agent 的本地进程

适用场景

  • 🌐 在 CNB 等云原生构建 / 开发环境里,起一个容器就能远程控制 codebuddy / codex / gemini / claude 等 AI 编程会话
  • 📱 本地开发时用浏览器(桌面或移动端)监控、介入容器里正在跑的 Agent
  • 🔗 在 CNB cloud-dev 中让 Agent 通过 MCP 按需生成端口预览链接,方便查看 npm run dev、静态服务等运行结果
  • 🚀 不想折腾部署 server、构建 web、装 CLI 这一串流程,想一条 docker run 解决问题

架构

三个组件依旧各司其职,只是住在同一个容器、并收敛成一个 Node 进程对外:

┌──────────────────── happy-cnb 容器 ─────────────────────┐
│                                                         │
│   happy-server  :8687                                   │
│     ├─ /v<N>/* REST + socket.io /v1/updates             │
│     └─ /, /_expo/*, /assets/*  (via @fastify/static)    │
│                    ▲                                    │
│                    │  同容器内 REST / Socket.io 通信      │
│                    │  (CNB 模式使用预共享 token)        │
│                    ▼                                    │
│   happy <agent>                                         │
│     ├─ 在 /workspace 里跑 AI 会话                        │
│     └─ Happy MCP:改标题 / CNB 端口转发                  │
│                                                         │
└─────────────────────────────────────────────────────────┘
           ▲                             ▲
           │ 浏览器(桌面 / 移动端)        │ -v $(pwd):/workspace

happy-app 和 happy CLI 之间仍经 happy-server 做同步与 RPC 中继。happy-cnb 是单用户、单容器的 CNB / 本地开发场景:自动登录使用预共享 bearer token,消息与会话数据在 CNB 模式下走 no-op 加密路径,不再宣称 server 无法读取数据。server 与前端静态资源由同一个 Fastify 进程服务,对外只暴露一个端口


快速开始

1. 构建镜像

docker build -f Dockerfile -t cnbcool/happy-cnb:latest .

2. 运行容器

docker run -it --rm \
  --name happy-cnb \
  -p 8687:8687 \
  -v "$(pwd)":/workspace \
  -v happy-cnb-data:/root/.happy-cnb \
  cnbcool/happy-cnb:latest

默认会在 /workspace 启动 happy codebuddy 会话。想换 Agent,把第一个位置参数换成目标 Agent,后续参数原样透传给 happy CLI:

# 使用 codex
docker run ... cnbcool/happy-cnb:latest codex

# 使用 codebuddy 并附加参数
docker run ... cnbcool/happy-cnb:latest codebuddy --model gpt-4o --permission-mode acceptEdits

# 使用 gemini
docker run ... cnbcool/happy-cnb:latest gemini

3. 浏览器连接

  1. 等终端打印 happy-cnb container is ready
  2. 打开浏览器访问 http://localhost:8687/ —— 直接进入主界面,无需注册 / 登录 / 扫码
  3. 主界面已能看到容器里 Agent 开出的会话,输入指令即可远程下发。移动端 Web 输入框已适配软键盘遮挡,并把回车键显示为「发送」。

容器启动时会生成一个随机 token 由 CLI 和 Web 前端共享(写在 /root/.happy-cnb/happy-home/access.key/root/.happy-cnb/happy-home/agent.key/app/web/auto-login.js),两侧属于同一个本地账号。凭据持久化在 happy-cnb-data volume,下次启动仍然是同一账号、同一套历史会话。

⚠️ 安全提醒:免登录意味着任何访问到 8687 端口的人都能接管这个账号。仅用于本地 / 受信任网络

4. 在同一容器内再开一条会话

入口脚本被软链到 /usr/local/bin/happy-cnb,检测到 server 已在跑时会跳过 bootstrap,只起 Agent:

docker exec -it <container> happy-cnb            # 默认 agent
docker exec -it <container> happy-cnb codex
docker exec -it <container> happy-cnb gemini

端口与卷

端口 / 卷说明
-p 8687:8687happy-server 对外端口(同时提供 Web 控制台与 API),浏览器访问 http://localhost:8687/。也支持挂在反向代理子路径下,前端会通过 cnb-env.js 自动识别 base path
-v $(pwd):/workspace交给 Agent 操作的项目目录
-v happy-cnb-data:/root/.happy-cnb持久化所有运行时状态:happy CLI 凭据(happy-home/)+ happy-server 的 PGlite 数据库 / 上传文件(happy-data/

可调环境变量

变量默认值说明
HAPPY_CNB_DEFAULT_AGENTcodebuddy未传 agent 参数时默认启动的 Agent
HAPPY_CNB_WORKDIR/workspaceAgent 启动前 cd 到的目录
HAPPY_HOME_DIR/root/.happy-cnb/happy-homehappy CLI 配置 / 凭据目录
APP_PORT8687happy-server 对外监听端口(唯一需要暴露的端口)
HAPPY_CNB_WEB_ROOT/app/webhappy-app 静态资源根目录
HAPPY_CNB_HIDDEN_PORTS未设置逗号分隔的端口列表;Agent 的 forward_port MCP 工具会拒绝把这些端口暴露到公网
HANDY_MASTER_SECRET自动生成并保存于 $HAPPY_HOME_DIR/master.secretserver master secret(用于 server 侧签名 / 服务令牌等,不代表 CNB 会话内容由客户端私有加密)
DATA_DIR / PGLITE_DIR/root/.happy-cnb/happy-data, /root/.happy-cnb/happy-data/pgliteserver 数据目录
HAPPY_CODEBUDDY_STALL_TIMEOUT_MS0(禁用)codebuddy agent 无响应多少毫秒后向 UI 回写错误。默认禁用,避免模型思考时间长被误判;设为正整数(如 90000)可开启失联保护
HAPPY_CNB_PERMISSION_MODEyolo注入给 codebuddy agent 的默认 --permission-mode,让 AI 在容器沙箱里直接执行 shell / git / 文件工具。设为空字符串可禁用注入,或改成 default / acceptEdits / plan
CODEBUDDY_BASE_URL未设置(用 SDK 默认端点)codebuddy agent 调用 LLM 的 API 端点,搭配 CODEBUDDY_API_KEY 使用
CODEBUDDY_API_KEY未设置codebuddy agent 调用 LLM 时使用的 API Key。本地 docker compose up 自托管 LLM 时必填
CODEBUDDY_MODEL未设置(使用 SDK 默认模型)覆盖 codebuddy agent 默认使用的模型名(如 gpt-4oclaude-sonnet-4deepseek-v3)。由底层 @tencent-ai/agent-sdk 读取生效;若启动时通过 --model 显式指定,则以 CLI 参数为准

安全提示

⚠️ 镜像的设计目标是本地或受信任网络使用

happy-cnb 为了 CNB / 本地单用户容器场景简化了认证与存储路径:Web 与 CLI 共享同一个 bearer token,CNB 模式下消息、会话元数据等不再按客户端私有加密模型处理。因此容器把 8687 端口暴露到宿主机且免登录使用时,不要直接把这个端口映射到公网。如需远程访问,建议:

  • 放在内网 / VPN / SSH 隧道之后
  • 或者反向代理时加 TLS + 访问控制
  • 不要把 APP_PORT、SSH、Docker daemon、数据库、调试器等基础设施端口公开;内置 forward_port MCP 工具也会拒绝转发常见基础设施端口,并对数据库 / debugger 等敏感端口给出提醒

CNB 端口预览

在真实 CNB cloud-dev 环境里,codebuddy 会拿到一个内置 Happy MCP server,除了自动改会话标题,还提供 forward_port 工具。用户启动开发服务后,可以让 Agent 在确认后把容器内 TCP 端口转换成 CNB 的公开预览 URL,例如:

帮我启动前端开发服务,并把端口 5173 暴露成预览链接

注意事项:

  • 该能力依赖 CNB 注入的 CNB_VSCODE_PROXY_URI,普通本地 docker run / docker compose 环境下会返回不可用说明
  • 转发前会检查端口是否真的在监听
  • APP_PORT、SSH、Docker daemon、metrics、code-server 等内部端口会被拒绝;数据库、缓存、Node inspector 等敏感端口会提示风险
  • 预览 URL 在工作区生命周期内有效,工作区销毁后失效

AI 模型后端

重要:镜像里打包的是 happy-cli + codebuddy agent,真正的 LLM 调用由 @tencent-ai/agent-sdk 里的 codebuddy-headless 完成。它需要一个可用的 AI 端点 + 凭据才能回复。

在 CNB 云原生构建平台里跑:

CNB 会自动注入凭证和端点 URL,开箱即用。

在个人机器上 docker compose up -d

  • 如果要本地跑出真实 AI 回复,需要自行提供可用的 LLM 凭据。典型做法:在 docker-compose.yml 的环境里设置 CODEBUDDY_BASE_URL + CODEBUDDY_API_KEY(或对应 agent 的官方凭据,例如 ANTHROPIC_API_KEYOPENAI_API_KEY
  • 默认会使用 SDK 内置的默认模型。若要切换具体模型,额外设置环境变量 CODEBUDDY_MODEL=<模型名>(例如 gpt-4oclaude-sonnet-4deepseek-v3)即可;也可以在启动 agent 时通过 happy-cnb codebuddy --model <模型名> 临时覆盖,CLI 参数优先级高于环境变量。

目录结构

happy-cnb/
├── Dockerfile                 # 一体化镜像(本项目主产物)
├── Dockerfile.server          # 仅 happy-server 的镜像
├── Dockerfile.webapp          # 仅 happy-app web 的镜像
├── happy-cnb/
│   ├── run.sh                 # 一体化镜像的入口脚本(= /usr/local/bin/happy-cnb)
│   ├── bootstrap-auth.ts      # 首次启动生成 token 并写给 CLI / Web
│   └── README.md              # 一体化镜像的详细说明
├── packages/                  # Happy monorepo(cli / server / app / wire / agent)
├── docs/                      # Happy 原项目与 happy-cnb 的架构 / 协议 / 设计文档
└── scripts/                   # 辅助脚本

致谢

本项目基于开源项目 slopus/happy 二次开发,特别感谢 Happy 团队与其社区贡献者:

  • 优雅地解决了「远程控制本地 AI CLI」这个痛点
  • 清晰的远程控制协议、同步模型和模块边界,为 happy-cnb 的单容器 / CNB 场景适配提供了扎实基础
  • 高质量的 monorepo 工程实践(happy-cli / happy-server / happy-app / happy-wire)让我们能在其之上快速构建一体化镜像

happy-cnb 在 Happy 的基础上聚焦于容器化一体分发 + CNB 云原生开发场景适配,只分发 Web 端(并适配移动端浏览器),不再包含原项目的 iOS / Android / macOS 客户端分发。原作者的所有贡献和权利依旧归属于 Happy 项目。

Happy 相关资源:


License

沿用上游 MIT License,详见 LICENSE

About

基于 slopus/happy 二次开发 适应 CNB 远程开发环境 和 本地 Docker 环境 支持一键开启Web Client for CodeBuddy Code

186.98 MiB
42 forks15 stars49 branches17 TagREADMEMIT license