166 lines
7.3 KiB
Markdown
166 lines
7.3 KiB
Markdown
# CreatorHub 单节点部署
|
||
|
||
本文档描述当前单节点方案:control-plane 管理业务和数据库,宿主机上的 native browser gateway 管理 Xvfb、预安装浏览器、Profile、CDP 与代理。Docker 只可作为 PostgreSQL 的独立部署方式,不参与浏览器生命周期。
|
||
|
||
## 服务与数据边界
|
||
|
||
| 服务 | 位置 | 责任 |
|
||
| --- | --- | --- |
|
||
| `creator-hub` | 宿主机或 Compose | Go control-plane 与前端静态文件 |
|
||
| native browser gateway | 宿主机 systemd user service | Xvfb、浏览器、Profile、runtime、CDP、代理 |
|
||
| PostgreSQL | 宿主机或 Compose | 业务、绑定、runtime generation、cleanup 和 lease 状态 |
|
||
|
||
gateway 以非 root 用户运行。每个 runtime 有独立的 Xvfb display、CDP/代理端口、systemd transient unit、临时目录、owner、generation 和日志;账号 Profile、正式素材和长期监听不属于任务临时清理对象。
|
||
|
||
当前目标是单机单节点。多节点调度、A/B 环境和跨机恢复不属于本轮部署步骤。
|
||
|
||
## 前置条件
|
||
|
||
宿主机必须具备:
|
||
|
||
- Linux、systemd user session 和可用的 `systemd-run --user`;
|
||
- Xvfb、`flock`、`curl`、`jq`、`openssl`;
|
||
- 合法的 fingerprint Chromium 及其绝对路径;浏览器以普通用户运行并保留 sandbox,禁止 `--no-sandbox`;
|
||
- 至少 20 GB 可用磁盘,Profile 缓存上限 20 GB,runtime 日志上限 1 GB;
|
||
- 如使用代理,准备真实可访问的 HTTP/HTTPS/SOCKS4/SOCKS5 出口及认证失败测试条件;
|
||
- PostgreSQL 17。Docker Compose 仅用于单独运行 PostgreSQL 时才需要 Docker。
|
||
|
||
预检:
|
||
|
||
```bash
|
||
id -u
|
||
systemctl --user is-system-running
|
||
command -v systemd-run systemctl Xvfb flock
|
||
systemd-run --user --wait --pipe --unit=creatorhub-preflight-$$ -- /usr/bin/true
|
||
```
|
||
|
||
## 安装 native gateway
|
||
|
||
复制配置并填写真实浏览器路径。配置文件只允许 gateway 用户读取:
|
||
|
||
```bash
|
||
install -d -m 0700 ~/.config/creatorhub
|
||
cp deploy/browser-gateway.env.example ~/.config/creatorhub/browser-gateway.env
|
||
chmod 600 ~/.config/creatorhub/browser-gateway.env
|
||
$EDITOR ~/.config/creatorhub/browser-gateway.env
|
||
```
|
||
|
||
关键配置:
|
||
|
||
- `LISTEN_ADDR=0.0.0.0:8081`:允许局域网 control-plane 联调;防火墙只放行受信网络;
|
||
- `GATEWAY_TOKEN`:至少 16 个字符,和控制面登记值完全一致;
|
||
- `BROWSER_PATH`、`BROWSER_VERSION`:预安装浏览器的绝对路径和版本;
|
||
- `BROWSER_STATE_DIR`:runtime 清单、锁和日志目录;
|
||
- `BROWSER_PROFILE_ROOT`:持久账号 Profile 根目录;不得指向临时目录;
|
||
- `RUNTIME_MIN_FREE_BYTES`、`RUNTIME_LOG_MAX_BYTES`、`PROFILE_CACHE_MAX_BYTES`:资源硬限制。
|
||
|
||
安装并启动 user service:
|
||
|
||
```bash
|
||
scripts/install-native-browser-gateway.sh
|
||
curl --fail --silent --show-error http://127.0.0.1:8081/healthz
|
||
curl --fail --silent --show-error -H "Authorization: Bearer ${GATEWAY_TOKEN}" http://127.0.0.1:8081/v1/info
|
||
systemctl --user --no-pager status creatorhub-browser-gateway.service
|
||
```
|
||
|
||
若 user service 不随登录启动,按主机运行规范启用 lingering;不要把 gateway 改成 root service:
|
||
|
||
```bash
|
||
loginctl enable-linger "$(id -un)"
|
||
```
|
||
|
||
## 运行 control-plane
|
||
|
||
### Compose 运行 control-plane 和 PostgreSQL
|
||
|
||
Compose 不再创建 gateway 服务,也不挂载 Docker socket:
|
||
|
||
```bash
|
||
export CREATORHUB_PORT=8080
|
||
export CONTROL_PLANE_USERNAME=creatorhub
|
||
export CONTROL_PLANE_PASSWORD="$(openssl rand -hex 24)"
|
||
export CREATORHUB_CREDENTIAL_MASTER_KEY="$(openssl rand -base64 32)"
|
||
|
||
docker compose config --quiet
|
||
docker compose up --detach --build
|
||
curl --fail --silent --show-error "http://127.0.0.1:${CREATORHUB_PORT}/healthz"
|
||
curl --fail --silent --show-error "http://127.0.0.1:${CREATORHUB_PORT}/readyz"
|
||
docker compose ps
|
||
docker compose logs --tail=200 creator-hub postgres
|
||
```
|
||
|
||
Compose 中的 control-plane 访问宿主机 gateway 时,网关 Endpoint 登记为 `http://host.docker.internal:8081`。裸机运行 control-plane 时登记为 `http://127.0.0.1:8081`。两种情况下都必须使用同一个 `GATEWAY_TOKEN`。
|
||
|
||
### 裸机开发
|
||
|
||
首次安装前端依赖:
|
||
|
||
```bash
|
||
npm --prefix web ci
|
||
```
|
||
|
||
分别在终端启动依赖和服务:
|
||
|
||
```bash
|
||
pnpm env # PostgreSQL
|
||
pnpm gateway # native browser gateway
|
||
pnpm backend # Go control-plane,Air 热加载
|
||
pnpm frontend # Vite,HMR
|
||
```
|
||
|
||
`pnpm backend` 不会隐式启动 PostgreSQL 或 gateway;`pnpm gateway` 直接运行当前用户的 native gateway,不要求 systemd。停止各服务时关闭对应终端即可。
|
||
|
||
默认联调地址:
|
||
|
||
| 服务 | 地址 |
|
||
| --- | --- |
|
||
| Vite | `http://127.0.0.1:5173` |
|
||
| control-plane | `http://0.0.0.0:8082` |
|
||
| native gateway | `http://0.0.0.0:8081` |
|
||
| PostgreSQL | `127.0.0.1:5432` |
|
||
|
||
## 首次配置与生命周期
|
||
|
||
1. 在「网关管理」登记 native gateway;读取 `/v1/info` 核对稳定 `node_id` 和浏览器版本能力。
|
||
2. 在「浏览器版本」登记 gateway 上存在的版本和绝对路径;版本缺失时创建动作必须失败,不得自动拉取或改用其它版本。
|
||
3. 创建账号和环境,选择账号、gateway、浏览器版本及可选网络出口。
|
||
4. 显式启动环境;gateway 返回 runtime ID、network ID、node ID、generation、display、CDP/代理端口和 readiness。
|
||
5. 登录二维码只在内存响应中短暂展示;完成人工登录后执行账号身份核验。
|
||
6. 采集和人工写操作必须通过账号身份、binding version、runtime generation 和 runtime use lease 检查。
|
||
7. 停止或失败时,业务结果和 cleanup 状态分别记录。cleanup 失败显示 `pending` 并可重试;不得把 pending 伪装为已停止。
|
||
8. 重新启动使用相同 Profile 根目录,核对浏览器版本和账号身份,不删除登录资料。
|
||
|
||
gateway 的 runtime 清单、Profile 和日志目录不得由 `docker compose down` 删除。只有明确授权时才执行账号 Profile 或正式素材删除。
|
||
|
||
## 验证与故障处理
|
||
|
||
代码检查:
|
||
|
||
```bash
|
||
python3 -m unittest discover -s browser_gateway -t . -p 'test_*.py' -q
|
||
python3 -m coverage run --source=browser_gateway --branch -m unittest discover -s browser_gateway -t . -p 'test_*.py' -q
|
||
python3 -m coverage report --omit='browser_gateway/test_*.py' --fail-under=65
|
||
go test ./...
|
||
go vet ./...
|
||
go build ./cmd/control-plane
|
||
go test -race ./...
|
||
npm --prefix web ci
|
||
npm --prefix web test -- --run
|
||
npm --prefix web run build
|
||
docker compose config --quiet
|
||
```
|
||
|
||
资源和失败场景必须由人工按 [native-browser-verification.md](native-browser-verification.md) 留证:Profile 占用、版本缺失、代理认证/网络失败、Xvfb 或浏览器启动失败、取消、超时、gateway 重启、重复清理、磁盘不足、旧 generation、监听与采集并行,以及真实抖音登录和采集。单元测试、Fake systemd 和 Mock gateway 不能替代真实平台证据。
|
||
|
||
常用诊断:
|
||
|
||
```bash
|
||
systemctl --user --no-pager --full status creatorhub-browser-gateway.service
|
||
journalctl --user -u creatorhub-browser-gateway.service --since=-30m
|
||
find ~/.local/state/creatorhub/browser-gateway -maxdepth 3 -type f -name runtime.json -print
|
||
curl --fail --silent --show-error http://127.0.0.1:8081/v1/browsers \
|
||
-H "Authorization: Bearer ${GATEWAY_TOKEN}"
|
||
```
|
||
|
||
强杀或网络中断后,不要重复发送真实平台写操作。先查询 control-plane 的运行、结果未知和 cleanup 状态,再按 generation 执行显式恢复或清理。
|