feat: unified one-time deploy summary

This commit is contained in:
Haitao Pan 2026-06-14 13:19:44 +08:00
parent 8cb46863d2
commit 656ca02a14
2 changed files with 494 additions and 21 deletions

View File

@ -0,0 +1,443 @@
# AI Workspace Runtime 交付规划
> 目标:把 `setup-ai-workspace-all-in-one.sh` 从“一组分散的基础设施 Playbook”收敛为一个**可直接使用的 AI Workspace Runtime 产品**——版本受控、运行模式可组合、对外仅暴露 Bridge、部署完成后输出一次性统一摘要。
>
> 本文是落地前的详细规划(设计 + 变更清单 + 提交/部署/验收方案)。实现阶段严格按本文执行,不扩大修改范围、不做大规模重构、优先复用现有实现。
- 状态:规划已定稿,待实现
- 影响仓库:`ai-workspace-infra/playbooks`、`ai-workspace-lab/xworkspace-console`、`ai-workspace-lab/xworkspace-core-skills`
- 目标主机:`root@acp-bridge.onwalk.net`
- 对外默认域名(唯一公开服务):`acp-bridge.onwalk.net`
---
## 1. 交付目标与验收标准
### 1.1 总体目标
1. 在不扩大修改范围、不做大规模重构的前提下,完成必要调整并分别提交三个仓库。
2. 使用 `scripts/setup-ai-workspace-all-in-one.sh` 将 AI Workspace 部署到 `root@acp-bridge.onwalk.net`
3. `xworkmate bridge` 统一使用 `acp-bridge.onwalk.net` 作为对外域名,且是**唯一默认公开**的服务。
4. 交付一个完整的 AI Workspace Runtime`xfce_desktop` + NodeJS + Playwright 全部版本受控。
5. 运行模式 `docker / k3s / systemd` 可选、可自由组合(`docker` 与 `k3s` 互斥,`docker + systemd` 可组合)。
6. 角色拆分:`roles/vhosts/xfce_xrdp_minimal` → `roles/vhosts/xfce_desktop_minimal_runtime` + `roles/vhosts/remote_desktop_xrdp_server`
7. 部署脚本结束后输出一份**面向最终用户**的统一部署摘要,重要认证信息**仅显示一次**。
### 1.2 验收标准Definition of Done
- [ ] 三个仓库完成代码提交,提供各自 Commit Hash。
- [ ] `setup-ai-workspace-all-in-one.sh` 在目标主机以远程 exec 模式执行成功(无 rsync仓库由远程主机自 GitHub pull
- [ ] Bridge 对外使用 `acp-bridge.onwalk.net`,其余服务默认不公开。
- [ ] 脚本结束输出统一部署摘要:访问入口、一次性凭据、各服务运行状态、可用 Agent CLI。
- [ ] `xfce_desktop / NodeJS / Playwright` 版本均可在单一来源role defaults查到并被固定。
---
## 2. 部署执行模型(远程 exec / GitHub pull
- `scripts/setup-ai-workspace-all-in-one.sh` 运行**在远程主机上**,全程 remote exec 模式。
- **不使用 rsync**;所需仓库由远程主机直接从 GitHub `pull`
- Playbooks`https://github.com/ai-workspace-infra/playbooks.git`
- Core Skills`https://github.com/ai-workspace-lab/xworkspace-core-skills.git`
- Console脚本自身所在仓库`https://github.com/ai-workspace-lab/xworkspace-console.git`
- QMD`https://github.com/ai-workspace-services/qmd.git`
- LiteLLM`https://github.com/ai-workspace-services/litellm.git`
- 含义:**本地提交必须推送到上述 GitHub 仓库后,远程部署才能拉到改动**。
> ⚠️ 注意仓库地址不一致playbooks 本地 `origin` 当前为 `git@github.com:x-evor/playbooks.git`,而部署权威源是 `ai-workspace-infra/playbooks`。实现阶段需将脚本中的 pull 源对齐到 `ai-workspace-infra/playbooks`,并把提交推送到该仓库。
### 2.1 环境变量接口契约(权威)
bootstrap 入口固定为 console 仓库的原始脚本,所有暴露/安全/可选桌面行为均通过 `bash -` 前的环境变量控制。
**标准安装**(默认安全本地工作区,仅需一个统一 token
```bash
curl -sfL https://raw.githubusercontent.com/ai-workspace-lab/xworkspace-console/main/scripts/setup-ai-workspace-all-in-one.sh | bash -
```
**全部参数(默认值与推荐用法):**
| 变量 | 默认 | 推荐用法 |
|---|---|---|
| `TOKEN` | 生成或复用 | 为 Bridge / Portal / LiteLLM / OpenClaw / Vault 设置**统一**认证 token |
| `AI_WORKSPACE_SECURITY_LEVEL` | `standard` | 公网/半公网主机使用 `strict` |
| `XWORKMATE_BRIDGE_PUBLIC_ACCESS` | `true` | Bridge 为默认唯一公开服务;如需关闭对外访问可显式设 `false` |
| `XWORKMATE_BRIDGE_DOMAIN` | host-specific | 设置 Bridge 公网域名,例如 `acp-bridge.onwalk.net` |
| `XWORKSPACE_CONSOLE_PUBLIC_ACCESS` | `false` | 仅当 Portal 必须公开时开启;本地优先更安全 |
| `XWORKSPACE_CONSOLE_ENABLE_XRDP` | `false` | 仅当需要远程桌面访问时开启 |
| `GATEWAY_OPENCLAW_PUBLIC_ACCESS` | `false` | 除非 OpenClaw 必须直接暴露,保持 false |
| `VAULT_PUBLIC_ACCESS` | `false` | 常规部署保持 false |
| `LITELLM_API_CADDY_STRICT_WHITELIST` | `false` | strict 且 LiteLLM 经 Caddy 暴露时开启 |
**进阶安装示例:**
```bash
curl -sfL https://raw.githubusercontent.com/ai-workspace-lab/xworkspace-console/main/scripts/setup-ai-workspace-all-in-one.sh | \
AI_WORKSPACE_SECURITY_LEVEL=strict \
XWORKSPACE_CONSOLE_ENABLE_XRDP=true \
XWORKSPACE_CONSOLE_PUBLIC_ACCESS=true \
XWORKMATE_BRIDGE_PUBLIC_ACCESS=true \
GATEWAY_OPENCLAW_PUBLIC_ACCESS=false \
VAULT_PUBLIC_ACCESS=false \
LITELLM_API_CADDY_STRICT_WHITELIST=true \
TOKEN="your-unified-auth-token" \
bash -
```
**目标主机ACP Bridge示例**
```bash
curl -sfL https://raw.githubusercontent.com/ai-workspace-lab/xworkspace-console/main/scripts/setup-ai-workspace-all-in-one.sh | \
XWORKMATE_BRIDGE_DOMAIN=acp-bridge.onwalk.net \
XWORKMATE_BRIDGE_PUBLIC_ACCESS=true \
AI_WORKSPACE_SECURITY_LEVEL=strict \
bash -
```
> 关键校准:`XWORKMATE_BRIDGE_PUBLIC_ACCESS` 默认 **`true`**——Bridge 是**默认唯一公开**的服务(域名经 `XWORKMATE_BRIDGE_DOMAIN` 自定义传入其余服务Console/OpenClaw/Vault/QMD/Hermes/PG/LiteLLM默认 `false`,保持 `127.0.0.1` 本地监听。如需关闭 Bridge 对外访问,显式设 `XWORKMATE_BRIDGE_PUBLIC_ACCESS=false`。`TOKEN` 输出务必私密保存——不得拷入前端源码或提交到 Git。
### 2.2 预期最终输出(部署摘要)
部署成功后,脚本将**一次性**打印部署域名与 token随后报告各服务运行状态
- AI Workspace 域名与 token仅显示一次
- OpenClaw
- QMD
- PostgreSQL
- Vault
- Workspace Portal / Console
- LiteLLM
- Hermes
- Agent CLIopencode、gemini、codex、claude
### 2.3 本地 macOS 校验模式
在 macOS 上脚本默认进入**本地校验模式**,在 `http://127.0.0.1:17000` 启动 Portal。若因端口占用校验失败先停止已有本地服务或在干净会话中重试。
---
## 3. 现状分析:角色层级关系
`setup-ai-workspace-all-in-one.sh`(位于 console 仓库)在目标主机引导后,运行 `setup-ai-workspace-all-in-one.yml`(位于 playbooks 仓库)。其按导入顺序的角色层级:
```
setup-ai-workspace-all-in-one.sh [repo: xworkspace-console/scripts]
└─ ansible-playbook setup-ai-workspace-all-in-one.yml [repo: playbooks]
├─1 setup-nodejs.yml → role roles/vhosts/nodejs NodeJS(22.x)+yarn
├─2 setup-xworkspace-console.yaml WORKSPACE PORTAL/CONSOLE内联 task无 role
│ apt: caddy,xfce4,python3,golang-go,google-chrome-stable,ttyd
│ git clone console → npm buildsystemd --user: console(:17000)/api(:8788)/ttyd(:7681)/status.timer
│ Caddy 公网站点 workspace.svc.plus ⚠ 标准模式下也公开
├─3 setup-ai-agent-skills.yml → role roles/ai_agent_runtime AI WORKSPACE RUNTIME 核心
│ NodeJS(24.x)+PlaywrightAgent CLI: opencode/gemini/codex/claudePython/browser/docs/fonts
│ └─ role agent_skills → 注入 xworkspace-core-skills 市场技能
├─4 deploy_gateway_openclaw.yml → role roles/vhosts/gateway_openclaw OpenClaw(2026.5.28)
├─5 deploy_xworkmate_bridge_vhosts.yml BRIDGE + ACP 集群
│ ├─ import setup-xworkspace-console.yaml带 bridge 变量再跑一次)
│ └─ roles: acp_server_codex / acp_server_opencode / acp_server_gemini /
│ acp_server_hermes / xworkmate_bridge(:8787 本地,公网 Caddy)
│ 域名默认 xworkmate-bridge.svc.plus → acp-bridge.onwalk.net
├─6 setup-vault.yaml → role roles/vhosts/vault Vault(1.20.4) :8200
├─7 setup-postgres-standalone.yaml → role roles/vhosts/postgres(dep: common) 原生 apt PG17 :5432
├─8 setup-litellm.yaml → role roles/vhosts/litellm pip 安装 :4000
├─9 deploy_QMD.yml → role roles/vhosts/qmd bun qmd, MCP :8181
├─10 deploy_agent_hermes.yml → role roles/vhosts/acp_server_hermes ⚠ Hermes 重复部署与步骤5重叠
└─11 setup-xfce-xrdp.yaml [可选] → role roles/vhosts/xfce_xrdp_minimal
→ 拆分为 xfce_desktop_minimal_runtime + remote_desktop_xrdp_server
```
### 3.1 关键发现
1. **公开面冲突**:步骤 2/5 在 `ai_workspace_security_level != strict` 时为 `workspace.svc.plus` 部署公网 Caddy 站点,导致 Portal 也对外暴露与“Bridge 唯一公开”冲突。
2. **Hermes 重复部署**:步骤 5ACP 集群内)与步骤 10独立各部署一次冗余。
3. **版本固定点分散**OpenClaw、Vault 已有固定变量NodeJS 有但偏宽松(`22.x`/`24.x`Hermes、QMD、LiteLLM 缺少显式版本/源固定。
---
## 4. 关键设计决策
### 4.1 对外公开面Bridge Only
- **Bridge 是默认唯一公开的服务**`XWORKMATE_BRIDGE_PUBLIC_ACCESS` 默认 `true`,公网域名由 `XWORKMATE_BRIDGE_DOMAIN` 自定义传入(目标主机 `acp-bridge.onwalk.net`)。如需关闭可显式设 `false`
- `xworkspace_console_public_access` 默认 `false`(仅 `XWORKSPACE_CONSOLE_PUBLIC_ACCESS=true` 时公开)。
- `GATEWAY_OPENCLAW_PUBLIC_ACCESS` / `VAULT_PUBLIC_ACCESS` 默认 `false`其余QMD / Hermes / PG / LiteLLM维持本地监听`127.0.0.1`),不部署公网 Caddy 站点。
- 实现方式:**最小改动**——仅调整默认值/开关并对齐 env 名称§2.1),不删除既有 public_access 能力(保留可手动放开)。
### 4.2 Hermes 去重
- `setup-ai-workspace-all-in-one.yml` 中移除步骤 10 的独立 `deploy_agent_hermes.yml` 导入(步骤 5 的 ACP 集群已含 hermes
- 保留 `deploy_agent_hermes.yml` 文件本身,供单独部署场景使用,仅从 all-in-one 聚合链里去重。
### 4.3 运行模式矩阵docker / k3s / systemd
引入一个**校验型**变量 `ai_workspace_runtime_modes`(列表),在 all-in-one 顶部加一段 `assert` 守卫,不重写各组件部署逻辑:
| 约束 | 规则 |
|---|---|
| 互斥 | `docker``k3s` 不可同时出现 |
| 可组合 | `docker + systemd` 允许;`systemd` 可单独 |
| 默认 | `['docker','systemd']`(多数 Agent 服务 systemdPostgreSQL 走 docker compose |
组件与模式映射(复用现有能力,不新增重型实现):
| 组件 | systemd | docker | k3s |
|---|---|---|---|
| Console / API / ttyd / Bridge / ACP / OpenClaw / QMD / LiteLLM | ✅ 默认 | — | — |
| PostgreSQL | 可选 | ✅ **默认 docker compose** | 可选 |
| Vault | `vault_deploy_mode=systemd` | — | `vault_deploy_mode=kubernetes`k3s |
守卫伪代码(放入 all-in-one 顶层 play
```yaml
- name: Validate runtime mode combination
hosts: all
gather_facts: false
tasks:
- assert:
that:
- not ('docker' in ai_workspace_runtime_modes and 'k3s' in ai_workspace_runtime_modes)
- ai_workspace_runtime_modes | length > 0
fail_msg: "docker 与 k3s 互斥;请选择 docker/k3s/systemd 的合法组合。"
```
### 4.4 PostgreSQL 默认 docker compose
- 新增开关 `postgresql_deploy_mode`,默认 `compose`
- `compose` 模式:在 `roles/vhosts/postgres` 增加一条 compose 部署路径(镜像版本固定,端口/口令复用现有变量),与现有原生 apt 路径并存、互斥择一。
- 不删除原生 apt 路径(设 `postgresql_deploy_mode=native` 可回退)。
### 4.5 QMD / LiteLLM 源仓库与版本固定
- QMD安装源指向 `https://github.com/ai-workspace-services/qmd.git`,新增 `qmd_source_repo` / `qmd_version` 变量固定。
- LiteLLM安装源指向 `https://github.com/ai-workspace-services/litellm.git`,新增 `litellm_source_repo` / `litellm_version` 变量固定。
---
## 5. 详细变更清单
### 5.1 角色拆分:`xfce_xrdp_minimal` → 两个角色
按职责拆分,**逐文件映射**,行为不变;`setup-xfce-xrdp.yaml` 改为顺序组合两个新角色。
**`roles/vhosts/xfce_desktop_minimal_runtime`(桌面运行时)**
| 来源 | 去向 | 说明 |
|---|---|---|
| `tasks/install.yml`(仅桌面包:`xfce4-session/xfwm4/xfdesktop4/xfce4-panel/xfce4-terminal/dbus-x11/fonts-noto-cjk/xserver-xorg-core` | `tasks/install.yml` | 移除 `xorgxrdp/xrdp` 包与 xrdp 服务启动 |
| `tasks/browser.yml`Google Chrome 固定版) | `tasks/browser.yml` | 原样保留 |
| 新增 `tasks/runtime.yml` | NodeJS + Playwright引用既有 `nodejs` / `ai_agent_runtime` 的固定版本变量) | 版本受控单一来源 |
| `defaults/main.yml`desktop/chrome/node/playwright 版本变量) | `defaults/main.yml` | 见 §5.2 版本表 |
**`roles/vhosts/remote_desktop_xrdp_server`(远程桌面 XRDP 服务)**
| 来源 | 去向 | 说明 |
|---|---|---|
| `tasks/install.yml``xorgxrdp/xrdp`、ssl-cert 组、daemon-reload、enable/start、unit 校验/fail | `tasks/install.yml` | XRDP 服务层 |
| `tasks/config.yml`(用户/口令 RDP 认证、`.xsession`、xfconf 目录) | `tasks/config.yml` | RDP 会话粘合 |
| `handlers/main.yml`Restart xrdp / sesman | `handlers/main.yml` | 原样保留 |
| `vars/main.yml``xfce_xrdp_services` 等)+ `xfce_rdp_port/xfce_enable_ufw` | `defaults`/`vars` | 端口/ufw |
**组合点 `setup-xfce-xrdp.yaml`**
```yaml
- name: Deploy XFCE desktop + optional XRDP (Optional)
hosts: all
become: true
vars:
xworkspace_console_enable_xrdp: false
tasks:
- include_role: { name: roles/vhosts/xfce_desktop_minimal_runtime }
- include_role: { name: roles/vhosts/remote_desktop_xrdp_server }
when: xworkspace_console_enable_xrdp | bool
```
> 旧角色 `roles/vhosts/xfce_xrdp_minimal`:拆分完成且引用全部切换后删除(当前唯一引用即 `setup-xfce-xrdp.yaml`)。
### 5.2 版本固定表(单一来源)
| 组件 | 变量 | 当前 | 目标 | 文件 |
|---|---|---|---|---|
| OpenClaw | `gateway_openclaw_required_version` | `2026.5.28` | `2026.6.1` | `roles/vhosts/gateway_openclaw/defaults/main.yml:23` |
| Vault | `vault_version`env 默认值) | `1.20.4` | `1.21.4` | `roles/vhosts/vault/vars/main.yml:6` |
| Hermes | `acp_hermes_version`(新增) | 无 | `0.15` | `roles/vhosts/acp_server_hermes/defaults/main.yml` |
| QMD | `qmd_version` / `qmd_source_repo`(新增) | 无 | 取自 `ai-workspace-services/qmd` | `roles/vhosts/qmd/defaults/main.yml` |
| LiteLLM | `litellm_version` / `litellm_source_repo`(新增) | 无 | 取自 `ai-workspace-services/litellm` | `roles/vhosts/litellm/defaults/main.yml` |
| NodeJS | `nodejs_version` / `ai_agent_runtime_nodejs_version` | `22.x` / `24.x` | 固定明确小版本 | `roles/vhosts/nodejs/defaults` + `roles/ai_agent_runtime/defaults` |
| Playwright | `ai_agent_runtime_playwright_version`(新增/固定) | 无显式 | 固定 | `roles/ai_agent_runtime/defaults/main.yml` |
| Google Chrome | `xfce_google_chrome_version` | `148.0.7778.167-1` | 保持固定 | 运行时角色 `defaults/main.yml` |
| XFCE | `xfce_packages` | 列表 | 保持apt 发行版固定) | 运行时角色 `defaults/main.yml` |
### 5.3 Bridge 对外域名(自定义参数,非硬编码默认)
- **`acp-bridge.onwalk.net` 是 host-specific 的自定义参数**,经 `XWORKMATE_BRIDGE_DOMAIN` 在部署时传入,**不写死为 role 默认值**。
- 实现要点(最小改动):确保 `XWORKMATE_BRIDGE_DOMAIN` 经 bootstrap 脚本 → playbook → `roles/vhosts/xworkmate_bridge` 正确透传。现有 env 覆盖链已支持:`XWORKMATE_BRIDGE_DOMAIN` → `ai_workspace_public_domain``SERVER_DOMAIN/ACP_BRIDGE_DOMAIN/BRIDGE_DOMAIN`)。
- `roles/vhosts/xworkmate_bridge/defaults/main.yml:47` 的中性回退默认值(`xworkmate-bridge.svc.plus`**保持不变**——仅作为未显式传参时的兜底;目标主机通过 `XWORKMATE_BRIDGE_DOMAIN=acp-bridge.onwalk.net` 指定真实域名。
- 验收只要求“Bridge 使用指定域名”,由自定义参数满足,无需改动 role 默认。
### 5.4 部署脚本统一摘要(`setup-ai-workspace-all-in-one.sh`
在现有脚本console 仓库,约 39KB末尾**追加**一段摘要渲染(探测主机实时状态,不硬编码),结构如下:
```
================ AI Workspace 部署摘要 ================
[访问入口]
Workspace Portal (Console) : http://127.0.0.1:17000 (本地)
XWorkMate Bridge : https://acp-bridge.onwalk.net ← 唯一公开
[一次性凭据](仅显示一次)
AI_WORKSPACE_AUTH_TOKEN : ********
Vault root token : ********
[服务状态]
Portal / Bridge / OpenClaw / QMD / Hermes / PostgreSQL / Vault / LiteLLM : active/inactive
[Agent CLI]
opencode / gemini / codex / claude : <version | 缺失>
======================================================
```
- 状态探测复用 console 的 `generate-status.py` 逻辑与各 role 的 `validate.yml` 健康检查(`systemctl is-active` + `curl` 健康端点)。
- 凭据“仅显示一次”:摘要从已落盘的 token 文件读取展示后,提示用户保存;脚本不重复打印。
### 5.5 all-in-one 聚合链调整
- 顶部新增 §4.3 运行模式 `assert` 守卫 play。
- 移除步骤 10 独立 `deploy_agent_hermes.yml` 导入(去重,见 §4.2)。
- 其余导入顺序保持不变。
---
## 6. 仓库与提交计划
| 仓库 | 主要改动 | Commit message建议 | 推送目标 |
|---|---|---|---|
| `playbooks` | 角色拆分、版本固定、Bridge 域名、运行模式守卫、PG compose、QMD/LiteLLM 源、聚合链去重、本规划文档 | `feat: deliver versioned AI Workspace Runtime (role split, run-mode matrix, bridge domain)` | `ai-workspace-infra/playbooks` |
| `xworkspace-console` | `setup-ai-workspace-all-in-one.sh` 统一摘要、pull 源对齐、console 默认不公开 | `feat: unified one-time deploy summary + bridge-only public surface` | `ai-workspace-lab/xworkspace-console` |
| `xworkspace-core-skills` | (按需)技能种子/版本对齐 | `chore: align skills seed for workspace runtime` | `ai-workspace-lab/xworkspace-core-skills` |
> 每个仓库**独立提交**,分别记录 Commit Hash 写入最终交付说明。
---
## 7. 部署与验证
### 7.1 部署命令(在目标主机或对其有网络/SSH 访问的环境执行)
```bash
# 远程 exec脚本在主机上自 GitHub pull 仓库并运行 ansible 到 localhost
# 采用 §2.1 权威环境变量契约(目标主机示例)
ssh root@acp-bridge.onwalk.net \
'curl -sfL https://raw.githubusercontent.com/ai-workspace-lab/xworkspace-console/main/scripts/setup-ai-workspace-all-in-one.sh | \
XWORKMATE_BRIDGE_DOMAIN=acp-bridge.onwalk.net \
XWORKMATE_BRIDGE_PUBLIC_ACCESS=true \
AI_WORKSPACE_SECURITY_LEVEL=strict \
bash -'
```
### 7.2 验证清单
- [ ] 脚本结束输出统一摘要,且 Bridge 显示 `https://acp-bridge.onwalk.net`
- [ ] `curl -I https://acp-bridge.onwalk.net` 可达;其余服务端口仅 `127.0.0.1` 监听。
- [ ] `systemctl --user is-active` 各服务为 `active`
- [ ] `opencode/gemini/codex/claude --version` 均可执行。
- [ ] 凭据仅在摘要中出现一次。
---
## 8. 风险与回退
| 风险 | 缓解 / 回退 |
|---|---|
| 沙箱无法直连 GitHub/目标主机 | 本地完成代码+提交push 与远程部署由有网络的环境执行 |
| PG 切 compose 影响既有数据 | 保留 `postgresql_deploy_mode=native` 回退路径 |
| 角色拆分回归 | `setup-xfce-xrdp.yaml` 组合两角色,行为等价;保留旧角色直至引用切换验证通过 |
| 版本固定导致拉取失败 | 版本变量集中、可单点覆盖env / `-e` |
---
## 9. 实现顺序(落地次序)
1. 本规划文档入库docs/)。
2. 角色拆分 + `setup-xfce-xrdp.yaml` 组合。
3. 版本固定OpenClaw/Vault/Hermes/QMD/LiteLLM/Node/Playwright/Chrome
4. Bridge 域名参数透传(`XWORKMATE_BRIDGE_DOMAIN`,自定义,不改 role 默认)。
5. 运行模式守卫 + PG compose 默认。
6. 聚合链去重Hermes+ console 默认不公开。
7. `setup-ai-workspace-all-in-one.sh` 统一摘要。
8. 三仓库分别提交,记录 Commit Hash。
9. 推送 + 远程部署 + 按 §7.2 验证。
---
## 附录 A. AI Workspace All-in-One Setupbootstrap 使用指南)
> 面向最终用户的官方安装指南,已合并入本规划作为单一权威来源。
> 本附录相对上游 README 有两处校准:① `XWORKMATE_BRIDGE_PUBLIC_ACCESS` 默认 **`true`**Bridge 为默认唯一公开服务);② `acp-bridge.onwalk.net`**host-specific 自定义参数**,经 `XWORKMATE_BRIDGE_DOMAIN` 传入。
这是从 `xworkspace-console` 仓库安装 AI Workspace Runtime 的推荐 bootstrap 入口。脚本以该仓库为公开入口,随后通过 AI Workspace playbooks 与各组件仓库准备运行时服务。
### A.1 标准安装
适用于默认安全的本地工作区,仅需一个生成或既有的统一 token
```bash
curl -sfL https://raw.githubusercontent.com/ai-workspace-lab/xworkspace-console/main/scripts/setup-ai-workspace-all-in-one.sh | bash -
```
### A.2 进阶安装
`bash -` 前用环境变量自定义暴露面、安全级别与可选桌面功能:
```bash
curl -sfL https://raw.githubusercontent.com/ai-workspace-lab/xworkspace-console/main/scripts/setup-ai-workspace-all-in-one.sh | \
AI_WORKSPACE_SECURITY_LEVEL=strict \
XWORKSPACE_CONSOLE_ENABLE_XRDP=true \
XWORKSPACE_CONSOLE_PUBLIC_ACCESS=true \
XWORKMATE_BRIDGE_PUBLIC_ACCESS=true \
GATEWAY_OPENCLAW_PUBLIC_ACCESS=false \
VAULT_PUBLIC_ACCESS=false \
LITELLM_API_CADDY_STRICT_WHITELIST=true \
TOKEN="your-unified-auth-token" \
bash -
```
### A.3 推荐参数
| 变量 | 默认 | 推荐用法 |
|---|---|---|
| `TOKEN` | 生成或复用 | 为 Bridge、Portal、LiteLLM、OpenClaw、Vault 设置一个统一认证 token |
| `AI_WORKSPACE_SECURITY_LEVEL` | `standard` | 公网/半公网主机使用 `strict` |
| `XWORKMATE_BRIDGE_PUBLIC_ACCESS` | `true` | Bridge 为默认唯一公开服务;需关闭对外访问时显式设 `false` |
| `XWORKMATE_BRIDGE_DOMAIN` | host-specific自定义 | Bridge 公网域名,例如 `acp-bridge.onwalk.net` |
| `XWORKSPACE_CONSOLE_PUBLIC_ACCESS` | `false` | 仅当 Portal 必须公开时开启;本地优先更安全 |
| `GATEWAY_OPENCLAW_PUBLIC_ACCESS` | `false` | 除非 OpenClaw 必须直接暴露,保持 false |
| `VAULT_PUBLIC_ACCESS` | `false` | 常规部署保持 false |
| `LITELLM_API_CADDY_STRICT_WHITELIST` | `false` | strict 部署且 LiteLLM 经 Caddy 暴露时开启 |
| `XWORKSPACE_CONSOLE_ENABLE_XRDP` | `false` | 仅当需要远程桌面访问时开启 |
### A.4 目标主机示例(当前 ACP Bridge 主机)
```bash
curl -sfL https://raw.githubusercontent.com/ai-workspace-lab/xworkspace-console/main/scripts/setup-ai-workspace-all-in-one.sh | \
XWORKMATE_BRIDGE_DOMAIN=acp-bridge.onwalk.net \
XWORKMATE_BRIDGE_PUBLIC_ACCESS=true \
AI_WORKSPACE_SECURITY_LEVEL=strict \
bash -
```
### A.5 预期最终输出
部署成功后,脚本**一次性**打印部署域名与 token随后报告以下服务状态
- AI Workspace 域名与 token
- OpenClaw
- QMD
- PostgreSQL
- Vault
- Workspace Portal / Console
- LiteLLM
- Agent CLIopencode、gemini、codex、claude
> Token 输出务必私密保存,不得拷入前端源码或提交到 Git。
### A.6 本地 macOS 校验
在 macOS 上脚本默认进入本地校验模式,在 `http://127.0.0.1:17000` 启动 Portal。若因端口占用导致校验失败先停止已有本地服务或在干净会话中重试。

View File

@ -15,6 +15,8 @@ set -euo pipefail
# GATEWAY_OPENCLAW_PUBLIC_ACCESS
# VAULT_PUBLIC_ACCESS
# XWORKSPACE_CONSOLE_ENABLE_XRDP
# AI_WORKSPACE_RUNTIME_MODES (docker,systemd by default; docker and k3s are mutually exclusive)
# POSTGRESQL_DEPLOY_MODE (compose by default; native for apt/systemd)
# AI_WORKSPACE_AUTH_TOKEN / XWORKSPACE_CONSOLE_AUTH_TOKEN
# / XWORKMATE_BRIDGE_AUTH_TOKEN / BRIDGE_AUTH_TOKEN / INTERNAL_SERVICE_TOKEN
# / DEPLOY_TOKEN
@ -577,78 +579,102 @@ service_status_line() {
local unit_patterns=$2
local port=${3:-}
local detail="not detected"
local state="DOWN"
local state="inactive"
if command -v systemctl >/dev/null 2>&1; then
local unit
for unit in $unit_patterns; do
if systemctl --user is-active --quiet "$unit" 2>/dev/null; then
state="active"
detail="systemd-user:$unit"
break
fi
if systemctl is-active --quiet "$unit" 2>/dev/null; then
state="OK"
state="active"
detail="systemd:$unit"
break
fi
done
fi
if [ "$state" != "OK" ] && [ -n "$port" ]; then
if [ "$state" != "active" ] && [ -n "$port" ]; then
if command -v ss >/dev/null 2>&1 && ss -ltn "( sport = :$port )" 2>/dev/null | grep -q ":$port"; then
state="OK"
state="active"
detail="port:$port"
elif command -v lsof >/dev/null 2>&1 && lsof -nP -iTCP:"$port" -sTCP:LISTEN >/dev/null 2>&1; then
state="OK"
state="active"
detail="port:$port"
fi
fi
printf ' - %-28s %s (%s)\n' "$label" "$state" "$detail"
printf ' %-28s : %-8s (%s)\n' "$label" "$state" "$detail"
}
cli_status_line() {
local label=$1
local bin=$2
local state="MISSING"
local state="missing"
local detail="not in PATH"
if command -v "$bin" >/dev/null 2>&1; then
state="OK"
detail="$(command -v "$bin")"
state="available"
detail="$("$bin" --version 2>/dev/null | head -n 1 || command -v "$bin")"
fi
printf ' - %-28s %s (%s)\n' "$label" "$state" "$detail"
printf ' %-28s : %-9s (%s)\n' "$label" "$state" "$detail"
}
print_deployment_summary() {
local domain=${SERVER_DOMAIN:-${XWORKMATE_BRIDGE_DOMAIN:-${BRIDGE_DOMAIN:-${ACP_BRIDGE_DOMAIN:-acp-bridge.onwalk.net}}}}
local token=$1
local vault_token="${VAULT_SERVER_ROOT_ACCESS_TOKEN:-$token}"
local vault_token_display="$vault_token"
local bridge_url="https://${domain}"
local portal_url="http://127.0.0.1:17000"
if [ "${XWORKMATE_BRIDGE_PUBLIC_ACCESS:-true}" != "true" ]; then
bridge_url="http://127.0.0.1:8787"
fi
if [ "$vault_token" = "$token" ]; then
vault_token_display="same as AI_WORKSPACE_AUTH_TOKEN"
fi
cat <<EOF
AI Workspace Deployment Summary
Domain: ${domain}
Token: ${token}
XWorkMate Bridge: https://${domain}
================ AI Workspace Deployment Summary ================
[Access]
Workspace Portal (Console) : ${portal_url}
XWorkMate Bridge : ${bridge_url}
AI workspace (runtime desktop/browser):
[One-time Credentials]
AI_WORKSPACE_AUTH_TOKEN : ${token}
Vault root token : ${vault_token_display}
[Service Status]
EOF
service_status_line "Runtime desktop/browser" "xworkspace-shell.service xworkspace-console.service display-manager.service gdm.service lightdm.service" "17000"
service_status_line "Workspace portal (console)" "xworkspace-console.service xworkspace-api.service" "17000"
service_status_line "XWorkMate Bridge (public)" "xworkmate-bridge.service xworkspace-bridge.service" "8787"
service_status_line "Portal / Console" "xworkspace-console.service xworkspace-api.service" "17000"
service_status_line "XWorkMate Bridge" "xworkmate-bridge.service xworkspace-bridge.service" "8787"
service_status_line "OpenClaw" "xworkspace-openclaw.service openclaw-gateway.service openclaw.service" "18789"
service_status_line "QMD" "qmd-mcp.service xworkspace-qmd.service qmd.service qdrant.service" "8181"
service_status_line "Hermes" "acp-hermes.service xworkspace-hermes.service hermes.service" "3920"
service_status_line "PG" "postgresql.service postgresql@16-main.service postgresql@15-main.service xworkspace-postgres.service" "5432"
service_status_line "PostgreSQL" "postgresql.service postgresql@17-main.service postgresql@16-main.service postgresql@15-main.service xworkspace-postgres.service" "5432"
service_status_line "Vault" "xworkspace-vault.service vault.service" "8200"
service_status_line "LiteLLM" "xworkspace-litellm.service litellm-proxy.service litellm.service" "4000"
service_status_line "Runtime desktop/browser" "xworkspace-shell.service display-manager.service gdm.service lightdm.service" ""
cat <<'EOF'
Agent CLI:
[Agent CLI]
EOF
cli_status_line "opencode" "opencode"
cli_status_line "gemini" "gemini"
cli_status_line "codex" "codex"
cli_status_line "claude" "claude"
printf '\n'
cat <<'EOF'
===============================================================
Save the one-time credentials above in a private location.
EOF
}
deploy_launch_agent() {
@ -899,6 +925,7 @@ if [ "$OS_NAME" = "darwin" ] && [ "${AI_WORKSPACE_DARWIN_MODE:-local}" = "local"
export VAULT_SERVER_ROOT_ACCESS_TOKEN="${VAULT_SERVER_ROOT_ACCESS_TOKEN:-$UNIFIED_AUTH_TOKEN}"
export VAULT_ADMIN_PASSWORD="${VAULT_ADMIN_PASSWORD:-$UNIFIED_AUTH_TOKEN}"
deploy_macos_local "$UNIFIED_AUTH_TOKEN"
print_deployment_summary "$UNIFIED_AUTH_TOKEN"
exit 0
fi
@ -960,11 +987,14 @@ append_var "AI_WORKSPACE_SECURITY_LEVEL" "ai_workspace_security_level"
append_var "LITELLM_API_CADDY_STRICT_WHITELIST" "litellm_api_caddy_strict_whitelist"
append_var "XWORKSPACE_CONSOLE_PUBLIC_ACCESS" "xworkspace_console_public_access"
append_var "XWORKMATE_BRIDGE_PUBLIC_ACCESS" "xworkmate_bridge_public_access"
append_var "XWORKMATE_BRIDGE_DOMAIN" "xworkmate_bridge_domain"
append_var "XWORKMATE_BRIDGE_VALIDATION_BASE_URL" "xworkmate_bridge_validation_base_url"
append_var "GATEWAY_OPENCLAW_PUBLIC_ACCESS" "gateway_openclaw_public_access"
append_var "VAULT_PUBLIC_ACCESS" "vault_public_access"
append_var "VAULT_DEPLOY_MODE" "vault_deploy_mode"
append_var "XWORKSPACE_CONSOLE_ENABLE_XRDP" "xworkspace_console_enable_xrdp"
append_var "AI_WORKSPACE_RUNTIME_MODES" "ai_workspace_runtime_modes"
append_var "POSTGRESQL_DEPLOY_MODE" "postgresql_deploy_mode"
# 4. Resolve one auth token for the bridge and downstream service UIs/APIs.
UNIFIED_AUTH_TOKEN="$(resolve_unified_auth_token)"