---
type: design
status: active
created: 2026-09-01
---
# 生产部署预设(供审批 · 未部署)
> 本预设对应 plan-final 的 **L2 满配 1GB 档**(可裁到 L0/L1 上线,见 §4)。目标环境:**primary 生产 Swarm(mgr1 `.51` / mgr2 `.52` / mgr3 `.53`,Engine 29.5.2)**——**2026-09-01 用户更正:prod 是 mgr 系节点,不是 dev-swarm;先全部署到 mgr1(.51)单节点测试,验收后再决定是否扩展三节点**。**本文是审批稿;mgr1 现为生产节点(PG/MinIO/WSG-prod :8562/ASW 等在跑),部署前须实机确认内存余量(`free -g`)与端口空闲(`ss -tln`,8640 在 inventory 无登记冲突)。**
> 数字口径与 `docs/plan-final-20260901.md` §2.2/2.3 一致(档标=常驻业务峰;cgroup=防暴走天花板允许超配)。
## 1. 服务清单总览(控制层 3 + Worker 层 5 + 备份 sidecar 1)
**测试期(当前预设):全部署于 mgr1(.51)单节点**;扩展期再按 §4-④ 分摊到 mgr1/2/3。
```mermaid
flowchart TB
subgraph MGR1[mgr1 · 192.168.1.51 · 测试期单节点全量]
GW[gateway ×1 · Go 自研 · 64m
host :8640]
SCH[scheduler ×1 · Go 自研 · 64m
SQLite 本地卷]
PM[proxymanager ×1 · Go 自研 · 32m]
MIH[mihomo 数据面 · v1.19.24 · 64m]
BAK[backup sidecar → NAS]
CN[searxng-cn · 192m]
TRA[trafilatura-http · 64m]
LP[lightpanda · 320m]
GLB[searxng-global · 192m]
SH[chrome-headless-shell · 400m
按需 0/1]
end
GW -->|localhost/overlay POST /enqueue| SCH
SCH --> CN & TRA & LP & GLB & SH
LP & SH & GLB -->|境外| MIH
SCH --- BAK
```
扩展期布局(测试通过后):mgr1 控制面(scheduler+PM+mihomo+gateway×1+备份);mgr2 国内组+轻渲染(searxng-cn/trafilatura/lightpanda);mgr3 国外组+保真(searxng-global/shell 按需/gateway×1)——mgr3 已有 central-proxy `:7890`,ProxyManager 订阅源届时可评估复用。
## 2. 逐服务详情
### 控制层(3 个自研服务,建议同仓三进程角色)
| 服务 | 技术栈(预设·待你确认 D7) | 镜像 | 副本/放置 | 资源 | 端口 |
|---|---|---|---|---|---|
| **gateway** | Go 1.x 单二进制(net/http + MCP Streamable HTTP handler + 内嵌策略库);理由:空载 <20MB、静态编译镜像 <30MB、并发模型省心 | `onesvm/browser-server:dev`(role=gateway) | 测试期 ×1 @mgr1;扩展期 ×2(mgr1+mgr3 漂移) | 64m / 0.25c | **host `:8640`**(ingress);MCP `POST /mcp` + HTTP `/v1/*`;反代前缀 `/bs-api` |
| **scheduler** | 同上二进制 role=scheduler(SQLite WAL 单写者 + Dock 适配器进程内模块 + 共享模版层整合器) | 同上 | **×1 钉 mgr1**(placement constraint `node.hostname==mgr1`) | 64m / 0.5c(**较 plan-final 的 32m 提额**,理由:D8 进程内适配器+模版层整合器驻留 scheduler;若 D8 改选 sidecar 形态则回 32m) | overlay `:8641`(仅内网 `/enqueue` `/pressure` `/metrics`;**待部署前登记 inventory**) |
| **proxymanager** | 同上二进制 role=proxymanager(订阅解析/探活/P2C/域名路由/合规规则热载) | 同上 | ×1 钉 mgr1 | 32m / 0.1c | overlay `:8642`(仅内网;**待部署前登记 inventory**) |
> **D7 技术栈决策点**:控制面三角色预设 **Go 单仓单二进制多角色**(理由见上)。备选 Python/FastAPI(组织内 WSG 先例、开发更快,但空载 ~60–90MB 且并发模型弱)。适配器实现形态预设:**scheduler 进程内 Go 模块**(引擎经 overlay HTTP/CDP 调用;零额外容器,内存最省;Dock 协议五方法作为内部 interface 约束,未来拆 sidecar 不改契约)。
### 数据面与有状态
| 项 | 内容 |
|---|---|
| SQLite 卷 | scheduler 本地卷(named volume + placement 钉 mgr1,禁跨节点共享卷) |
| 备份 | `backup` sidecar(×1 mgr1):日备 SQLite → NAS `browser-server-backup/`(对齐组织 NAS sidecar 惯例;O11 恢复演练待定) |
| 代理数据面 | **mihomo** `metacubex/mihomo:v1.19.24`(实测版本),×1 mgr1,64m;mixed 端口仅 overlay 暴露(`17890`,**待部署前登记 inventory**);订阅经 `PROXY_SUB_URLS` env 注入 |
### Worker 层(5 个第三方/自构建引擎,全部版本 pin)
| 服务 | 镜像(pin) | 放置(测试期全部 mgr1;扩展期见 §1) | cgroup | 说明 |
|---|---|---|---|---|
| searxng-cn | `searxng/searxng:2026.8.29-d226b78bc`(digest b36af798…) | mgr1(扩展期 mgr2) | 192m | 引擎:baidu/sogou/360/bing-cn;上游并发钳 4–8(scheduler 侧限流) |
| trafilatura-http | 自构建 `onesvm/trafilatura-http:dev`(python:3.12-slim + trafilatura==2.2.0) | mgr1(扩展期 mgr2) | 64m | 正文精读;semaphore=8 |
| lightpanda | `lightpanda/browser:0.3.7`(digest eae2c7f8…) | mgr1(扩展期 mgr2) | 320m | JS 轻渲染 4 槽;`shell_active ⇒ 停新`互斥 |
| searxng-global | 同 searxng 镜像第二实例 | mgr1(扩展期 mgr3) | 192m | 引擎:bing 主(D2:Bing-only 姿态);境外经 mihomo |
| chrome-headless-shell | `chromedp/headless-shell:151.0.7922.109`(digest 2d349b54…) | mgr1(扩展期 mgr3) | 400m | **按需槽**:平时 replicas=0,保真任务由 scheduler 经 Swarm API 拉起(冷启动 5–10s),空闲 10min 回收;CONCURRENT=1 |
> L2 常驻 cgroup 天花板合计:64×2+64+32+64+192+64+320+192 = **1056m ≈ 1GB**(scheduler 因 D8 由 32m 提额至 64m,故较 plan-final §2.3 的 1024m +32m;档标=常驻业务峰不变,天花板为超配口径,仍在 1GB 档内;若 D8 改选 sidecar 形态则 scheduler 回 32m、天花板回 1024m);shell 400m 按需不计入常驻。
## 3. 网络 / 端口 / 密钥
- **overlay**:新建 `browser-server-net`;联调 Vlepontas 时附加到 primary 上已有的 `vlepontas-casa-net`(vlepontas-prod 在用,alias `browser-server`),审批后执行
- **对外**:仅 gateway `:8640`(ingress)+ 反代 `/bs-api`;scheduler/PM/mihomo/引擎全部仅 overlay
- **密钥**(全部 docker secret 或 `${VAR:?required}`,禁默认值禁入 git):`BROWSER_SERVER_ADMIN_TOKEN`(管理面)、`BROWSER_SERVER_KEYS_SEED`(key hash 盐)、`PROXY_SUB_URLS`(订阅,多订阅逗号分隔容灾)
- **认证**:消费者 `X-Service-Token: bs_…`;管理面仅 overlay + admin token
## 4. 上线档位与扩容触发器
| 步 | 内容 | 触发下一步的条件 |
|---|---|---|
| ⓪ mgr1 测试 | **全部署于 mgr1 单节点**(控制面+国内组+mihomo/PM+searxng-global+lightpanda,shell 按需)≈700MB–1GB 档 | 你亲自测试通过(功能/体感) |
| ① L0 | 控制面 + 国内组(searxng-cn + trafilatura)≈350MB 档 | 国内链路联调通过 |
| ② L1 | + mihomo/PM + searxng-global + lightpanda ≈700MB 档 | 国外链路验收通过 |
| ③ L2 | + gateway×2 + shell 按需槽 ≈1GB 档;评估是否扩展三节点 | 进入生产常态 |
| ④ L3 1.5GB | shell 常驻 + searxng 双副本 | `/pressure` 渲染等待 p95 超标或冷启动被感知(见 plan-final §2.5) |
**部署流程**(组织惯例):Mac 构建 `--platform linux/amd64`(或 mgr1 本机 DaoCloud mirror)→ `docker save | ssh root@.51 'docker load'`(测试期仅 mgr1;扩展期每节点 load)→ `docker stack deploy -c stacks/browser-server.yml --resolve-image never`。**O12**:amd64 首部署后同架构复测内存档位再锁档标。**🟡 前置确认**(部署执行时再做):mgr1 内存余量 `free -g`、端口 `ss -tln | grep 8640`、现有 stack 影响面与回滚(`docker stack rm`)。
## 5. 待你拍板(本预设新增)
| # | 项 | 提议 |
|---|---|---|
| D7 | 控制面技术栈 | **Go 单仓单二进制多角色**(备选 Python/FastAPI) |
| D8 | 适配器形态 | **scheduler 进程内模块**(零额外容器;备选 sidecar/引擎,+~120MB) |
| D9 | 上线节奏 | **①→②→③ 三步灰度**(可合并为一次全量) |
| D10 | 联调网络 | 附加 `vlepontas-casa-net`(对齐 WSG 先例) |
(D1–D6 见 plan-final §7:你已确认 D2=Bing-only;D3 `:8640`/`/bs-api` 等仍待你点头。)
## 6. 镜像 tag 约定(O13 落地)
- **日常迭代复用 `:dev`**:`onesvm/browser-server:dev`(控制面三角色单二进制)与 `onesvm/trafilatura-http:dev`(引擎)同名覆盖推送/加载,自动回收旧层,不每次另起新 tag。
- **里程碑/联调临时 tag** `:v0.1.x` 或 `:dev--`:仅用于回滚锚点或并行验证,合并/验证通过后及时删除。
- 第三方引擎镜像(searxng / mihomo / lightpanda / headless-shell / alpine)**tag + digest 双锁**(见 stacks/browser-server.yml),不属于复用覆盖范畴。
- 传输流程不变:Mac `--platform linux/amd64` 构建 → `docker save | ssh root@192.168.1.51 'docker load'` → `--resolve-image never` 部署(§4 部署流程)。