# 实施说明 — 服务端 Playwright Chromium 远程浏览器 > 设计:`docs/design/specs/2026-06-11-server-browser-chromium-design.md` > **Worker 购机/装机**:[`2026-06-11-browser-worker-server-procurement.md`](./2026-06-11-browser-worker-server-procurement.md) ← **先买服务器** ## 部署形态(2026-06-11 更新) **选定独立 Worker**,不在 Nexus 主站 `Dockerfile.prod` 安装 Chromium。 | 仓库路径 | 运行位置 | |----------|----------| | `browser-worker/` | Worker VPS | | `server/.../browser_bridge.py` 等 | Nexus 主站 | ## 涉及文件(计划) | 文件 | 动作 | 位置 | |------|------|------| | `browser-worker/Dockerfile` | **新建** | Worker | | `browser-worker/docker-compose.yml` | **新建** | Worker | | `browser-worker/main.py` | Worker FastAPI + WS + Playwright | Worker | | `browser-worker/browser_url_safe.py` | SSRF(与主站共享逻辑或复制) | Worker | | `server/utils/browser_url_safe.py` | SSRF(桥接层二次校验) | Nexus | | `server/infrastructure/browser/worker_client.py` | HTTP/WS 连 Worker | Nexus | | `server/api/browser_session.py` | REST + 管理员 WS 桥接 | Nexus | | `server/main.py` | 注册 router;`NEXUS_BROWSER_*` | Nexus | | `server/config.py` | `browser_enabled`, `browser_worker_url`, `worker_secret` | Nexus | | `tests/test_browser_url_safe.py` | SSRF 单测 | Nexus | | `tests/test_browser_worker_client.py` | mock Worker | Nexus | | `frontend/src/composables/useRemoteBrowserSession.ts` | canvas + WS | 前端 | | `frontend/src/components/GlobalBrowserPanel.vue` | iframe → canvas | 前端 | | `frontend/src/composables/useGlobalBrowser.ts` | 对接 remote session | 前端 | **不变**:~~`server/api/browser.py`~~ **已删除**(2026-06-11);Worker 方案将新建 `browser_session` API,不复用 iframe 状态接口。 **不修改**:`Dockerfile.prod`(主站) ## 实现步骤 ### Phase W0 — 你购机(并行) 按 procurement 文档:**2C4G+、Ubuntu 22.04/24.04、防火墙 8443 仅 Nexus IP**。 ### Phase W1 — Browser Worker 服务 1. `browser-worker/` 独立 FastAPI:`GET /health`、`POST /v1/sessions`、`DELETE`、`WS /v1/sessions/{id}/stream` 2. Header `X-Nexus-Worker-Key` 校验 3. Playwright Chromium + CDP screencast + 键鼠 4. SSRF 在 Worker 侧强制执行 ### Phase W2 — Nexus 桥接 1. `worker_client.py`:创建/销毁会话、WS 双向转发 2. `browser_session.py`:管理员 JWT WS ↔ Worker WS 3. `NEXUS_BROWSER_ENABLED=0` → 503 ### Phase W3 — 前端 1. `useRemoteBrowserSession.ts` + canvas 2. `GlobalBrowserPanel` 替换 iframe 3. 503 友好提示 ### Phase W4 — 联调(需 Worker IP) 1. Worker 部署 + ufw 2. Nexus `.env` 配 `NEXUS_BROWSER_WORKER_*` 3. 验收表(procurement §5 Phase D) 4. changelog + audit → 门控 → 部署 ## 测试要点 ```bash pytest tests/test_browser_url_safe.py tests/test_browser_ui_state.py -q cd frontend && npm run type-check # Worker 目录(实现后) cd browser-worker && pytest -q ``` ## 依赖与配置 **Nexus 主站** ```env NEXUS_BROWSER_ENABLED=1 NEXUS_BROWSER_WORKER_URL=https://10.x.x.x:8443 NEXUS_BROWSER_WORKER_SECRET= NEXUS_BROWSER_MAX_SESSIONS=2 NEXUS_BROWSER_IDLE_TIMEOUT_SEC=1800 ``` **Worker `.env`** ```env WORKER_SECRET= WORKER_BIND=0.0.0.0:8443 WORKER_MAX_SESSIONS=2 WORKER_IDLE_TIMEOUT_SEC=1800 ``` ## 回滚 1. `NEXUS_BROWSER_ENABLED=0` + 重启 Nexus 2. Worker 容器 `docker compose down`(主站不受影响)