# Hybrid Deployment Guide · Cloudflare Pages + 腾讯云轻量

> v0.3.0-rc1 · 见 [ADR-005](adr/ADR-005-hybrid-deployment.md) 决策背景
>
> 把 boss-skills 拆成静态层 + API 层分别部署. 静态走 Cloudflare CDN ($0), API 走腾讯云 VM (70-80 元/月). 整体最优 cost / speed / 安全。

---

## 0. 架构总览

```
                                  ┌──── 用户 (国内 / 海外) ────┐
                                  │                          │
                                  │  浏览器看 docs            │ curl 调 API
                                  ▼                          ▼
       ╔══════════════════════════╗            ╔═══════════════════════╗
       ║  Cloudflare Pages        ║            ║  腾讯云轻量 (CN-1)     ║
       ║  · landing.html          ║            ║  · uvicorn boss_server║
       ║  · 5 showcase            ║            ║  · attribution cron   ║
       ║  · openapi.json          ║            ║  · anchors/raw (700)  ║
       ║  · README                ║            ║  · nginx + SSL        ║
       ║                          ║            ║                       ║
       ║  $0 · 全球 CDN           ║            ║  ~70-80 元/月 · 2C2G  ║
       ║  boss-vault.pages.dev    ║            ║  api.boss-vault.com   ║
       ║  或自定义域名             ║            ║                       ║
       ╚══════════════════════════╝            ╚═══════════════════════╝
                ▲                                       ▲
                │ push to main                          │ git pull
                │ Cloudflare GitHub integration         │ systemctl restart
                └──────── GitHub (source) ──────────────┘
```

**职责拆分**:

| 资源 | 性质 | host | 成本 |
|---|---|---|---|
| `landing.html` | 公开, 无 secret | Cloudflare Pages | $0 |
| `docs/showcase/*.html` (5 个) | 公开, 无 secret | Cloudflare Pages | $0 |
| `docs/api/openapi.json` | 公开 API spec | Cloudflare Pages | $0 |
| `README.md` 渲染 | 公开 | Cloudflare Pages | $0 |
| `scripts/boss_server.py` (5 endpoint) | 有 secret, long-running | 腾讯云 systemd | $10/月 |
| `scripts/attribution_check.py` (cron) | 有 secret + 数据 | 腾讯云 systemd timer | (含上面) |
| `anchors/<slug>/raw/` (data) | confidential | 腾讯云 home (chmod 700) | (含上面) |

---

## 1. 决策框架 · 你需要哪几层?

不一定一次全部署. 按你的实际需求挑:

| 你的场景 | A 静态 (Cloudflare) | B API (腾讯云) | C Cron + Data (腾讯云) |
|---|---|---|---|
| 想给外部人看 docs / 信息图 | ✅ 必做 | ❌ 不必 | ❌ 不必 |
| 想让外部 LLM runtime 调 API | ✅ 必做 | ✅ 必做 | (可选, attribution 可推迟) |
| 想 always-on attribution cron | ✅ 必做 (展示) | ✅ 必做 (API trigger) | ✅ 必做 (cron) |
| 完整生产 + 飞书 push + 多 anchor | ✅ 必做 | ✅ 必做 | ✅ 必做 + 升 4C8G |

**最低 MVP** = A only. 静态文档对外公开, API 完全本地 Claude Code 跑.

---

## 2. Phase 1 · Cloudflare Pages 静态部署 (推荐立即做)

**时间**: 10-30 min · **成本**: $0 · **风险**: 0

### 2.1 · 前置

- [x] GitHub repo 公开 (已: zhanglunet/boss-vault)
- [x] **www/ + docs/internal/ 拆分完成** (2026-05-28): 公网内容在 `www/`, 内部文档在 `docs/internal/`
- [x] **public-safe preflight 通过**: `python3 scripts/check_public_safe.py` 25/25 PASS (硬规则 0 命中)
- [ ] Cloudflare 账号 (免费注册)
- [ ] (可选) 自定义域名 (例: boss-skills.example.com)

> **重要**: `redact_check.py` 把 `docs/` + `www/` 都加 allowlist (允许 methodology placeholder).
> CF 公网部署需要更严的 preflight — 用 `check_public_safe.py` 只扫硬规则 (真名 / 内部 URL), 默认扫 `www/`.

### 2.2 · 步骤

0. **preflight (必跑)**:
   ```bash
   python3 scripts/check_public_safe.py
   # 期望: ✅ check_public_safe PASSED — 25 文件 0 硬规则命中, 公网部署安全
   ```

1. **登录 Cloudflare** (dash.cloudflare.com) · Workers & Pages 菜单 · Create application · Pages · Connect to Git

2. **授权 GitHub** · 选 `zhanglunet/boss-vault` repo

3. **配置 build**:
   ```
   Project name:        boss-vault          (默认, → boss-vault.pages.dev)
   Production branch:   main
   Framework preset:    None (静态)
   Build command:       (留空)
   Build output:        www                 ← 关键 (不是 docs)
   Root directory:      /                   (默认)
   ```
   说明: `www/index.html` 是 CF Pages 默认首页 (内容 = 原 landing.html marketing 页).
   `docs/internal/` 不在 build path, CF Pages 根本拿不到, 无需 exclude / redirects 拦截.

4. **(已配) www/_redirects 历史兼容**: 仅 1 条规则保留对老书签 `/landing.html` 的兼容
   ```
   /landing.html        /index.html         301
   ```

5. **第一次 deploy** · 点 Save and Deploy · ~ 30s 完成

6. **验证**:
   - `https://boss-vault.pages.dev/` → 对外门户 marketing (= 原 landing 内容)
   - `https://boss-vault.pages.dev/landing.html` → 301 重定向到 `/`
   - `https://boss-vault.pages.dev/docs.html` → 文档总览
   - `https://boss-vault.pages.dev/showcase/2026-05-28-anchor-wiki.html` → 锚点 Wiki
   - `https://boss-vault.pages.dev/showcase/2026-05-29-hybrid-deploy.html` → Hybrid Deploy SPA
   - `https://boss-vault.pages.dev/api/openapi.json` → API spec JSON
   - `https://boss-vault.pages.dev/adr/ADR-005-hybrid-deployment.md` → ADR-005 markdown (raw)
   - `https://boss-vault.pages.dev/internal/prd-v3.1.md` → **404** (不在 build path)

7. **(可选) 自定义域名** · Custom domains · Add a domain · 填入你的域名 · Cloudflare 自动配 DNS + SSL

### 2.3 · CI/CD 自动化

push 到 main → Cloudflare Pages GitHub integration 自动 deploy. 无需 GitHub Actions.

每次 deploy 都有独立 URL (例 `cf12ab.boss-vault.pages.dev`), 可以 preview 后再 promote.

### 2.4 · 故障排查

| 现象 | 根因 | 修法 |
|---|---|---|
| **Build fail · pip install pydantic-core 卡** | CF 探测 `requirements.txt` 自动 pip install · Python 3.13 与 pydantic-core 不兼容 | **加环境变量 `SKIP_DEPENDENCY_INSTALL=1`** (Production + Preview 都加) · 静态站根本不需 pip · build command 设 `echo "static"` 也只能 cover B 阶段, auto-install 在 A 阶段在前 |
| **部署成功但访问显示 "Hello world"** | 创建项目时误进 Workers tab → 创建了 Worker, 默认模板返回 Hello world · 不是 Pages | 项目 URL 是 `*.workers.dev` 不是 `*.pages.dev` 就确认是 Worker · 解绑 custom domain → 删 Worker → 重新创建时**顶部 tab 切到 Pages** |
| **`/internal/*` 返回 200 + 首页 (非 404)** | CF Pages 默认 "soft 404" — unknown URL fallback 到 `index.html` 200 | 加 `www/404.html` (CF 自动用作 404) + `www/_redirects` 显式拦 `/internal/*` `/docs/internal/*` 等 → 强制返回 404 |
| **跨目录 link 全 broken (.../README.md 等 404)** | vault root / docs/internal/ 文件不在 `www/` build output 里 · 相对路径 `../../X` 在公网解析不到 | 把所有跨 build output 边界的引用改为 absolute github URL (`https://github.com/.../blob/main/X`) · build output 内部 sibling 引用保留相对 |
| **404 on home (`/` 路径)** | 没有 `www/index.html` 或 `_redirects` 未配 | 确认 `www/index.html` 存在; 或 `_redirects` 加 `/  /landing.html  302` |
| **国内访问慢** | Cloudflare 默认含 China Network 但有限 | 若仍慢, 启用 Argo Smart Routing (~ $5/月) |
| **Stale content** | CF 边缘 cache | dash → Cache → Purge Everything (一键) |
| **新 commit 后 build 没触发** | GitHub integration 未授权 / branch 不匹配 | Settings → Builds & deployments → 检查 Production branch = `main` · 看最近 webhook delivery 是否 200 |

**关键 "3 个默认坑" 速记 (ADR-005 Phase 1 部署实战痛点)**:

| # | 坑 | 表象 | 解药 |
|---|---|---|---|
| 1 | auto-install Python deps | build fail | env `SKIP_DEPENDENCY_INSTALL=1` |
| 2 | 创建默认进 Workers tab | Hello world | 显式点 Pages tab |
| 3 | 200 SPA fallback | `/internal/*` 200 而非 404 | `404.html` + `_redirects` 显式拦截 |

详见复盘 `docs/internal/dev-log/2026-05-28_cf-pages-live-deploy.md` §3.2-§3.5.

---

## 3. Phase 2 · 腾讯云轻量部署 API (按需启动)

**时间**: 1-2 小时 · **成本**: 70-80 元/月 (2C2G 年付) · **风险**: 中 (需 SSH 运维)

### 3.1 · 启动信号

满足任一即启动 (来自 ADR-005 §5.3):
- 外部 user 明确要求 "我想 curl 你们 API"
- 内部团队 ≥ 3 人需要 always-on
- D3 GitHub Actions schedule 高峰延迟 (实测 > 51 min) 影响 attribution

不满足这些信号 → 不浪费 80 元/月.

### 3.2 · 购买配置

**腾讯云轻量** (访问 cloud.tencent.com/lighthouse):

| 项 | 推荐 |
|---|---|
| Region | 广州 / 上海 / 北京 (按你团队 IP 最近) |
| OS | Ubuntu Server 22.04 LTS |
| Plan | 2C2G 40GB SSD · 4Mbps 峰值 · 300GB/月流量 |
| 价格 | ~ 70 元/月 (年付优惠) |
| 续费 | 至少 1 年 (避免 cron 期间被删) |
| 公网 IP | 自带 (固定) |
| 防火墙 | 仅开 22 + 80 + 443 (默认配置后改) |

**域名**:
- 选项 A · 你已有域名 → DNS 加 `api.your-domain.com` A 记录指向 VM 公网 IP
- 选项 B · 没域名 → 买一个 (.com ~ 10 美元/年)
- DNS 用 Cloudflare 管理 (与 Phase 1 同账号)

### 3.3 · 系统初始化 (SSH 后跑)

```bash
# 1. SSH 登入 (用腾讯云控制台 reset root password)
ssh root@<vm-public-ip>

# 2. 创建 boss user (避免用 root 跑服务)
adduser boss
usermod -aG sudo boss
mkdir /home/boss/.ssh
cp ~/.ssh/authorized_keys /home/boss/.ssh/
chown -R boss:boss /home/boss/.ssh
chmod 700 /home/boss/.ssh
chmod 600 /home/boss/.ssh/authorized_keys

# 3. 关 root SSH (用 boss user 后)
nano /etc/ssh/sshd_config
# PermitRootLogin no
# PasswordAuthentication no
systemctl restart sshd

# 4. ufw 防火墙
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable

# 5. 装基础工具 (退出 root, 用 boss user)
exit
ssh boss@<vm-public-ip>

sudo apt update && sudo apt upgrade -y
sudo apt install -y python3.11 python3-pip python3-venv git nginx certbot python3-certbot-nginx
```

### 3.4 · 部署 boss-vault

```bash
# 1. clone repo (公开 repo, 无需 SSH key)
cd ~
git clone https://github.com/zhanglunet/boss-vault.git
cd boss-vault

# 2. 装 Python 依赖
python3.11 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

# 3. 配 .env
cp .env.example .env
nano .env
# 填:
#   ANTHROPIC_API_KEY=sk-ant-...
#   (可选) LARK_APP_ID / LARK_APP_SECRET
chmod 600 .env

# 4. 测一下 server 能起
python3 -m uvicorn scripts.boss_server:app --host 127.0.0.1 --port 8421 &
sleep 3
curl http://localhost:8421/v1/healthz
# 期望: {"status":"ok","timestamp":"..."}
pkill -f uvicorn
```

### 3.5 · systemd 服务 (always-on)

```bash
# 1. 用 templates 模板
sudo cp templates/boss-hermes.service.example /etc/systemd/system/boss-hermes.service

# 2. 替换占位符
sudo sed -i \
    "s|__VAULT_ROOT__|/home/boss/boss-vault|g; \
     s|__USER__|boss|g" \
    /etc/systemd/system/boss-hermes.service

# 3. (重要) 改 ExecStart 用 venv 的 uvicorn
sudo nano /etc/systemd/system/boss-hermes.service
# 改成:
# ExecStart=/home/boss/boss-vault/.venv/bin/uvicorn scripts.boss_server:app \
#     --host 127.0.0.1 --port 8421 --workers 1 --no-access-log

# 4. enable + start
sudo systemctl daemon-reload
sudo systemctl enable boss-hermes
sudo systemctl start boss-hermes
sudo systemctl status boss-hermes
# 期望: active (running)

# 5. 看 log
journalctl -u boss-hermes -f
```

### 3.6 · nginx 反向代理 + SSL

```bash
# 1. 用 templates 模板
sudo cp templates/nginx-boss-hermes.conf.example /etc/nginx/sites-available/boss-api

# 2. 替换占位符 (改成你的域名)
sudo sed -i "s|__DOMAIN__|api.your-domain.com|g" /etc/nginx/sites-available/boss-api

# 3. 启用 site
sudo ln -sfn /etc/nginx/sites-available/boss-api /etc/nginx/sites-enabled/
sudo nginx -t                                     # 语法检查
sudo systemctl reload nginx

# 4. 配 DNS (Cloudflare dash)
#    Type: A
#    Name: api
#    Content: <vm-public-ip>
#    Proxy: DNS only (灰云, 不走 Cloudflare proxy)
#    Cloudflare 代理 API 会导致 30s 超时 + 国内访问绕远, 关掉

# 5. 配 SSL (Let's Encrypt 免费, 自动 90 天续)
sudo certbot --nginx -d api.your-domain.com
# 选择: redirect HTTP to HTTPS

# 6. 验证
curl https://api.your-domain.com/v1/healthz
# 期望: {"status":"ok",...}
```

### 3.7 · attribution cron (systemd timer)

```bash
# 1. 创建 service
sudo tee /etc/systemd/system/boss-attribution.service > /dev/null <<EOF
[Unit]
Description=boss-vault attribution checker (daily)
After=network-online.target

[Service]
Type=oneshot
User=boss
WorkingDirectory=/home/boss/boss-vault
EnvironmentFile=/home/boss/boss-vault/.env
ExecStart=/home/boss/boss-vault/.venv/bin/python3 scripts/attribution_check.py run

[Install]
WantedBy=multi-user.target
EOF

# 2. 创建 timer (每天 09:00 北京时间 = UTC 01:00)
sudo tee /etc/systemd/system/boss-attribution.timer > /dev/null <<EOF
[Unit]
Description=Run boss attribution daily at 09:00 CST

[Timer]
OnCalendar=*-*-* 01:00:00 UTC
Persistent=true

[Install]
WantedBy=timers.target
EOF

# 3. enable + start
sudo systemctl daemon-reload
sudo systemctl enable boss-attribution.timer
sudo systemctl start boss-attribution.timer
sudo systemctl list-timers --all | grep boss
# 期望: 下次触发时间显示
```

### 3.8 · 安全 / 监控

```bash
# 1. ufw 状态
sudo ufw status verbose

# 2. fail2ban (防 SSH brute force)
sudo apt install fail2ban
sudo systemctl enable fail2ban

# 3. 监控 (最简)
# 看 systemd 日志: journalctl -u boss-hermes -n 100
# 看 nginx 日志: tail -f /var/log/nginx/boss-api.access.log
# 看 attribution: journalctl -u boss-attribution.service

# 4. (可选) 加 Cloudflare Health Check (cloudflare-pages 免费 1 个)
#    URL: https://api.your-domain.com/v1/healthz
#    Frequency: 5 min
#    Alert: email
```

### 3.9 · 部署 checklist

| 项 | 命令 / 验证 |
|---|---|
| ✅ VM SSH | `ssh boss@<vm-ip>` |
| ✅ boss user + ufw | `sudo ufw status` |
| ✅ Python 3.11 + venv | `python3 --version` |
| ✅ repo clone + deps | `cd ~/boss-vault && pip list` |
| ✅ .env + API key | `grep ANTHROPIC_API_KEY .env` |
| ✅ uvicorn local test | `curl http://localhost:8421/v1/healthz` |
| ✅ systemd boss-hermes | `systemctl status boss-hermes` |
| ✅ nginx + SSL | `curl https://api.your-domain.com/v1/healthz` |
| ✅ attribution timer | `systemctl list-timers \| grep boss` |
| ✅ DNS Cloudflare | `dig api.your-domain.com` |

全部 ✅ → API 上云成功.

---

## 4. 总成本

| Phase | 资源 | 价格 |
|---|---|---|
| Phase 1 | Cloudflare Pages (含 China Network) | **$0/月** |
| Phase 1 + 自定义域名 | .com 域名 | ~ 10 美元/年 (≈ 6 元/月) |
| Phase 2 (年付) | 腾讯云轻量 2C2G 40GB | ~ 70 元/月 |
| Phase 2 + monthly | 腾讯云轻量 2C2G 40GB | ~ 80-100 元/月 |
| **合计 (Phase 1 + 2)** | | **~ 76-110 元/月** |
| 对比单 VM 全栈 (4C8G) | 阿里云 / AWS | 250-500 元/月 |

**省 30-70% 同时性能更好** (国内外 docs 速度比单 VM 快 3-5x).

---

## 5. 故障 / 灾难恢复

### 5.1 · 静态层 (Cloudflare Pages)

- **页 404** · check `docs/_redirects` 配置 / build output 路径
- **deploy 失败** · check GitHub repo 是否 public + Cloudflare GitHub permission
- **DDoS** · Cloudflare 自动防护 (free plan 已含)
- **重新构建** · dash → Deployments → Retry

### 5.2 · API 层 (腾讯云)

- **systemd boss-hermes inactive** · `journalctl -u boss-hermes -n 200` 看 error, 通常是 .env 缺 ANTHROPIC_API_KEY 或 port 占用
- **nginx 502** · check uvicorn 是否在 127.0.0.1:8421 听 (`ss -tlnp`)
- **SSL 过期** · certbot 自动续, 若失败 `sudo certbot renew --dry-run` 排查
- **VM 宕机** · 腾讯云控制台 reboot · 数据在 SSD 不丢
- **VM 彻底丢失** · 拉新 VM + git clone + .env 从 1Password 恢复 + 跑 §3.3-3.7 步骤

### 5.3 · 数据层 (anchors/raw/, cases/, reports/)

- **gitignored 不入 git** · 唯一 source of truth = VM 磁盘
- **备份** (重要): `rsync -av --exclude '.git' ~/boss-vault/{anchors,cases,reports} backup-server:/backup/boss-vault/$(date +%Y%m%d)/`
- **本地 Mac 同步备份**: 每周 rsync 一次到本地

---

## 6. 升级路径 (未来)

| 触发信号 | 升级动作 |
|---|---|
| API QPS > 5/s | uvicorn `--workers 4` (2C2G 仍够) |
| API QPS > 20/s | 升 4C8G (~ 250 元/月) + 4 workers |
| 多 anchor (≥ 3) | 升 4C8G + 加 docker compose |
| 实时通知 | 加 Lark webhook (templates/nginx 已配 /feishu/event) |
| 国际用户 | 加 Cloudflare Argo Smart Routing ($5/月) 或多 region VM |
| 数据 ≥ 50 GB | 升 80GB 或 100GB plan |

---

## 7. 相关文档

- [ADR-003](adr/ADR-003-deployment-as-optional.md) · deployment 三形态可选
- [ADR-004](adr/ADR-004-boss-skills-as-product.md) · boss-skills as a product
- [ADR-005](adr/ADR-005-hybrid-deployment.md) · 本文档 positioning 决策
- [`docs/deployment.md`](deployment.md) · 三形态对比 (D1/D2/D3)
- [`docs/api/integration-cookbook.md`](api/integration-cookbook.md) · 客户端接入示例
- [`templates/boss-hermes.service.example`](../templates/boss-hermes.service.example) · systemd unit
- [`templates/nginx-boss-hermes.conf.example`](../templates/nginx-boss-hermes.conf.example) · nginx config

---

*deployment-hybrid.md · v1 · 2026-05-28 · 见 ADR-005*
