基于code-server打造私有AI编程工作站

简介

Code Server 是什么?

Code Servercoder.com 开发的运行在远程服务器上的 VS Code。它将完整的 VS Code 体验搬到浏览器中,让你可以在任何设备上使用熟悉的 IDE,而无需在本地安装任何东西。

  • 浏览器即开发环境Chromebook、平板、手机都能写代码
  • 统一开发环境:团队成员无论用什么设备,都能获得一致的 VS Code 体验
  • 服务器算力:编译、测试、下载等重活交给服务器,笔记本更省电

HAPI 是什么?

HAPI(GitHub: tiann/hapi)是一个让 AI 编程助手能够远程控制和协作的工具。它支持 Claude CodeCodexGeminiOpenCode 等主流 AI CLI,让你:

  • 无缝切换:本地干一半,出门用手机继续
  • AFK 审批:离开电脑?用手机一键审批 AI 的代码修改请求
  • 终端随身带:通过 Web 界面或手机控制 AI 编程任务
  • E2E 加密WireGuard + TLS 加密,数据安全有保障

HAPIHappy 最大的区别,Happy 使用一个集中服务器来存储你的加密数据。HAPI 是去中心化的——每个用户运行自己的集线器,中继服务器只转发加密流量,不存储任何内容。

为什么选择 HAPI + Code Server?

相信很多小伙伴会遇到这些问题:

  1. 出门在外想改代码:身边只有手机或平板,总不能背着的电脑吧?
  2. 电脑配置不够:跑 AI CLI 风扇转不停,电池掉得飞快
  3. 想躺着也能审核 AI 的代码:让 AI 干完活,醒来再审批

HAPI + Code Server 的组合完美解决这些问题:

  • Code ServerVS Code 搬到浏览器里——无论你用 iPad、手机还是借别人的电脑,浏览器一开就能写代码
  • HAPIAI CLI 也能远程控制——人在外面也能手机点点,让群晖上的 AI 帮你写代码
  • 数据完全本地化——代码存在自己的群晖上,不用担心泄露到第三方云服务

这就是你的私有 AI 编程工作站:白天出门用手机指挥 AI 干活,晚上回家在平板上审核代码,全部围绕的是你自己的群晖,而不是某个云厂商。

主要特点

  • 浏览器即开发环境Code ServerVS Code 在浏览器中运行,无需本地安装
  • AI 随时可用:集成 6 款主流 AI CLIClaude CodeCodexGeminiOpenCodeiFlowQwen Code
  • 远程控制:通过 HAPIWeb 界面或手机端远程控制 AI 编程任务
  • 数据本地化:所有代码和数据存储在群晖上,隐私有保障

应用场景

  • 在任何设备(电脑、平板、手机)上通过浏览器进行开发
  • 外出时通过手机远程控制 AI 完成编程任务
  • 利用群晖的大容量存储管理多个项目
  • 企业内网部署,保护代码安全

安装

在群晖上以 Docker 方式安装。

关于 code-server 可以看老苏之前写的文章,但本次结合了 HAPI,所以会有一些变化

文章传送门:在线代码编辑器code-server

准备工作

在群晖的 docker 文件夹中创建以下目录结构:

1
2
# 新建文件夹和子目录
mkdir -p /volume1/docker/code-server/{config,projects}

文件夹 装载路径 说明
/volume1/docker/code-server/config /config 配置目录
/volume1/docker/code-server/projects /config/workspace 项目代码目录

端口

本地端口 容器端口 说明
3196 8443 Code Server Web UI
3197 3197 HAPI 服务端口

环境变量

可变 说明
PUID 1000 用户 UID
PGID 1000 用户 GID
TZ Asia/Shanghai 时区
PASSWORD admin123 Web 登录密码
SUDO_PASSWORD admin123 终端 sudo 密码
CODE_SERVER_PORT 3196 Code Server 端口映射
DEFAULT_WORKSPACE /config/workspace 默认工作目录
CLI_API_TOKEN admin123 HAPI API 令牌,建议使用强密码
HAPI_LISTEN_HOST 0.0.0.0 HAPI 监听地址
HAPI_LISTEN_PORT 3197 HAPI 监听端口
HAPI_PUBLIC_URL http://192.168.0.197:3197 网页分享链接
HAPI_API_URL http://192.168.0.197:3197 Runner 连接地址

⚠️ 请将 HAPI_PUBLIC_URLHAPI_API_URL 中的 IP 地址替换为你的群晖实际 IP 地址

docker run 方式

如果你熟悉命令行,可能用 docker cli 更快捷

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 进入目录
cd /volume1/docker/code-server

# 运行容器
docker run -d \
--name ai-dev-vscode \
--restart unless-stopped \
-p 3196:8443 \
-p 3197:3197 \
-v $(pwd)/config:/config \
-v $(pwd)/projects:/config/workspace \
-e PUID=1000 \
-e PGID=1000 \
-e TZ=Asia/Shanghai \
-e PASSWORD=admin123 \
-e SUDO_PASSWORD=admin123 \
-e CODE_SERVER_PORT=3196 \
-e DEFAULT_WORKSPACE=/config/workspace \
-e CLI_API_TOKEN=admin123 \
-e HAPI_LISTEN_HOST=0.0.0.0 \
-e HAPI_LISTEN_PORT=3197 \
-e HAPI_PUBLIC_URL=http://192.168.0.197:3197 \
-e HAPI_API_URL=http://192.168.0.197:3197 \
linuxserver/code-server:latest

docker-compose 方式(推荐)

将以下内容保存为 docker-compose.yml 文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
version: '3.8'
services:
code-server:
image: linuxserver/code-server:latest
container_name: ai-dev-vscode
restart: unless-stopped
shm_size: 512mb
ports:
- 3196:8443
- 3197:3197
volumes:
- ./config:/config
- ./projects:/config/workspace
environment:
- PUID=1000
- PGID=1000
- TZ=Asia/Shanghai

- PASSWORD=admin123
- SUDO_PASSWORD=admin123
- CODE_SERVER_PORT=3196
- DEFAULT_WORKSPACE=/config/workspace

- CLI_API_TOKEN=admin123
- HAPI_LISTEN_HOST=0.0.0.0
- HAPI_LISTEN_PORT=3197
- HAPI_PUBLIC_URL=http://192.168.0.197:3197
- HAPI_API_URL=http://192.168.0.197:3197

然后执行一键启动:

1
2
3
4
5
# 进入目录
cd /volume1/docker/code-server

# 一键启动
docker-compose up -d

安装 AI 编程环境

首次运行容器后,需要在容器内执行初始化脚本安装 AI CLIHAPI

之所以没有重新写 Dockerfile ,是为了更灵活,这样可以使用标准的 code-server,并且可以根据需要升级 AI CLI

setup-code.sh

将下面的内容保存为安装脚本 setup-code.sh,放入到 config 目录中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#!/usr/bin/env bash
set -euo pipefail

echo "🚀 [AI Dev Setup] 安装 Node.js + 6 个 AI CLI + HAPI (code-server 专用)..."

if [ "$(id -u)" -ne 0 ]; then
echo "❌ 请用 root 运行:docker exec -u root ai-dev-vscode /config/setup-code.sh"
exit 1
fi

have_cmd() {
command -v "$1" >/dev/null 2>&1
}

have_global_npm_pkg() {
local pkg="$1"
npm list -g "$pkg" --depth=0 >/dev/null 2>&1
}

echo "🔧 安装基础系统工具..."
apt-get update -y
apt-get install -y \
git curl vim tmux htop jq wget unzip \
build-essential ca-certificates \
python3 python3-pip

echo "🧹 清理系统中可能冲突的 nodejs/npm..."
apt-get purge -y nodejs npm || true
rm -rf /usr/bin/node /usr/bin/npm /usr/local/bin/node* /usr/local/bin/npm* || true

echo "🟦 用 NodeSource 安装 Node.js 22.x..."
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
apt-get install -y nodejs

if ! have_cmd node; then
echo "❌ node 安装失败"
exit 1
fi
if ! have_cmd npm; then
echo "❌ npm 安装失败"
exit 1
fi

# npm cache 放在 /config/.npm,后面统一 chown 给 abc
mkdir -p /config/.npm
npm config set cache /config/.npm

echo "✅ Node: $(node -v)"
echo "✅ npm: $(npm -v)"

if have_cmd npx; then
echo "✅ npx: $(npx -v)"
else
echo "⚠️ 警告:npx 不在 PATH,后续使用 npx 相关命令可能失败。"
fi

echo "🛠 配置 npm 全局目录为 /usr/local..."
mkdir -p /usr/local/lib/node_modules /usr/local/bin
npm config set prefix /usr/local
npm config set audit false
npm config set fund false

echo "💾 安装 AI CLI(检测已安装则跳过)..."

# 1. Claude Code (@anthropic-ai/claude-code)
if have_cmd claude || have_global_npm_pkg "@anthropic-ai/claude-code"; then
echo " → Claude Code 已安装,跳过 (@anthropic-ai/claude-code)"
else
echo " → 安装 Claude Code (@anthropic-ai/claude-code)"
if ! npm install -g @anthropic-ai/claude-code@latest; then
echo "⚠️ Claude Code 安装失败,请稍后重试。"
fi
fi

# 2. Gemini CLI (@google/gemini-cli)
if have_cmd gemini || have_global_npm_pkg "@google/gemini-cli"; then
echo " → Gemini CLI 已安装,跳过 (@google/gemini-cli)"
else
echo " → 安装 Gemini CLI (@google/gemini-cli)"
if ! npm install -g @google/gemini-cli@latest; then
echo "⚠️ Gemini CLI 安装失败,请检查网络或包名。"
fi
fi

# 3. OpenAI Codex (@openai/codex)
if have_cmd codex || have_global_npm_pkg "@openai/codex"; then
echo " → OpenAI Codex 已安装,跳过 (@openai/codex)"
else
echo " → 安装 OpenAI Codex (@openai/codex)"
if ! npm install -g @openai/codex@latest; then
echo "⚠️ Codex 安装失败,请检查网络或包名。"
fi
fi

# 4. OpenCode (opencode-ai) - 修正包名为 opencode-ai(无 @)
if have_cmd opencode || have_global_npm_pkg "opencode-ai"; then
echo " → OpenCode 已安装,跳过 (opencode-ai)"
else
echo " → 安装 OpenCode CLI (opencode-ai)"
if npm install -g opencode-ai@latest; then
echo " → OpenCode npm 安装成功"
else
echo " → npm 安装失败,尝试官方一键脚本..."
curl -fsSL https://opencode.ai/install | bash || echo "⚠️ OpenCode 一键安装也失败,请手动检查网络/权限"
fi
fi

# 5. iFlow CLI (@iflow-ai/iflow-cli)
if have_cmd iflow || have_global_npm_pkg "@iflow-ai/iflow-cli"; then
echo " → iFlow CLI 已安装,跳过 (@iflow-ai/iflow-cli)"
else
echo " → 安装 iFlow CLI (@iflow-ai/iflow-cli)"
if ! npm install -g @iflow-ai/iflow-cli@latest; then
echo "⚠️ iFlow 安装失败,请检查网络或包名。"
fi
fi

# 6. Qwen Code (@qwen-code/qwen-code)
if have_cmd qwen-code || have_global_npm_pkg "@qwen-code/qwen-code"; then
echo " → Qwen Code 已安装,跳过 (@qwen-code/qwen-code)"
else
echo " → 安装 Qwen Code (@qwen-code/qwen-code)"
if ! npm install -g @qwen-code/qwen-code@latest; then
echo "⚠️ Qwen Code 安装失败,请检查网络或包名。"
fi
fi

echo "💾 安装 HAPI(全局)..."
# 7. HAPI (@twsxtd/hapi) - 你已经验证这条命令可用
if have_cmd hapi || have_global_npm_pkg "@twsxtd/hapi"; then
echo " → HAPI 已安装,跳过 (@twsxtd/hapi)"
else
echo " → 安装 HAPI (@twsxtd/hapi)"
if ! npm install -g @twsxtd/hapi@latest; then
echo "⚠️ HAPI 安装失败,请检查网络或包名。"
fi
fi

echo "📁 创建工作目录..."
mkdir -p /config/workspace/{go,node,python,rust,web}

echo "🧩 写入 /config/ai-init.sh..."

cat > /config/ai-init.sh << 'EOL'
#!/bin/bash
echo "🔧 AI Dev 环境加载..."

# AI CLI 别名
alias claude='claude'
alias gemini='gemini'
alias codex='codex'
alias opencode='opencode'
alias iflow='iflow'
alias qwen='qwen'

alias ll='ls -lah'
alias ws='cd /config/workspace && ls -la'

# HAPI 快捷命令(使用全局 hapi)
alias hapi-server='hapi hub --relay'
# 如果你更喜欢 server 模式,可以改成:
# alias hapi-server='hapi server --relay'
alias hapi='hapi'

# AI 状态检查
ai-status() {
echo "📁 当前目录: $(pwd)"
echo "🔧 AI CLI:"
command -v claude >/dev/null && echo " ✅ claude" || echo " ❌ claude"
command -v gemini >/dev/null && echo " ✅ gemini" || echo " ❌ gemini"
command -v codex >/dev/null && echo " ✅ codex" || echo " ❌ codex"
command -v opencode >/dev/null && echo " ✅ opencode" || echo " ❌ opencode"
command -v iflow >/dev/null && echo " ✅ iflow" || echo " ❌ iflow"
command -v qwen >/dev/null && echo " ✅ qwen" || echo " ❌ qwen"
command -v hapi >/dev/null && echo " ✅ hapi" || echo " ❌ hapi"
}

echo "✅ 运行 ai-status 测试!"
EOL

chmod +x /config/ai-init.sh

# ⚠️ 这里假设 abc 的 uid/gid 是 1000:1000,如不同请替换
chown -R 1000:1000 \
/config/workspace \
/usr/local/bin \
/usr/local/lib/node_modules \
/config/.npm

echo "✅ 安装完成!访问 http://192.168.0.197:3196"
echo "📋 密码: admin123"
echo "📋 终端: source /config/ai-init.sh && ai-status"
echo "📋 如需 HAPI: hapi server # 或直接 hapi"

⚠️ setup-code.sh 可以根据需要进行调整,用不上的 AI CLI 可以删除

第一次启动后,或者在 code-server 变更了后,执行一次安装脚本 setup-code.sh 即可

1
2
# 进入容器(以 root 身份)运行安装脚本
docker exec -u root ai-dev-vscode /config/setup-code.sh

执行完成后,就可以开始使用了

运行

访问 Code Server

在浏览器中输入 http://群晖IP:3196

  • 密码:admin123

需要信任 workspace 目录

安装中文插件之后,可以让界面显示中文

访问 HAPI

HAPI 提供 Web 界面和远程控制功能,为了方便说明,老苏拆解后进行演示和说明

code-server 开启三个终端

终端1

运行下面👇的命令, 提供中心服务 HAPI Hub

1
2
# 启动 hapi hub 服务
hapi server

终端2

opencode 为例,在 opencode 能正常运行后,执行下面的命令,启动 AI 代理会话

1
2
# 启动 AI 代理会话
hapi opencode

如果你是用 claude 也是一样的,可以用 hapi 启动

除此之外,还支持 geminicodex

终端3

执行下面的命令运行 hapi runner服务,它负责注册机器到 Hub,让网页能看到并远程启动会话

1
2
# 启动 hapi runner 服务
hapi runner start

网页

在浏览器中输入 http://群晖IP:3197

  • 密码:admin123

登录后的主界面

会看到有一个 opencode 的会话

回到 code-server

你会发现两边是同步的

通过设置,可以将 HAPI 的默认语言改为中文

移动端

跟网页端是一样的密码

也能同步看到任务的进行

小结

这是老苏为热爱自由的开发者打造的本地优先 AI 代理平台。以上只是抛砖引玉,从安全角度出发,老苏不建议暴露到公网,远程访问建议使用 tailscale 或者 zerotier

现在,你拥有了一台可以随时随地进行 Vibe Coding 的个人工作站,不仅能在电脑浏览器里远程使用 Visual Studio Code,也可以在手机上轻松接入同一套开发环境,随时继续你的创作。

参考文档

linuxserver/docker-code-server
地址:https://github.com/linuxserver/docker-code-server

tiann/hapi: App for Claude Code / Codex / Gemini / OpenCode, vibe coding anytime, anywhere
地址:https://github.com/tiann/hapi

HAPI - Vibe Coding Anytime, Anywhere
地址:https://hapi.run/

Quick Start | HAPI
地址:https://hapi.run/docs/guide/quick-start