thread-master/docs/product/haixun-deployment/plan.md

182 lines
8.3 KiB
Markdown
Raw Permalink Normal View History

2026-07-20 06:33:14 +00:00
# Plan: 設定驅動的多主機正式部署
> Status: `draft-for-review`
> Source: `requirements.md`, `spec.md`
> Last updated: `2026-07-18`
> Implementation: not started; this plan does not authorize a live deployment
## 1. 交付策略
1. 先建立設定 schema、preflight 與空 VM bootstrap再碰正式服務。
2. 先完成 WireGuard 與 Registry確保後續 image 只需本機 build、遠端 pull。
3. 資料層先行Atlas connectivity、Redis persistence、MinIO persistence/bucket/backup。
4. 將現有共同 release 拆成 frontend、backend、worker、crawler、ops images。
5. 先單節點驗證,再做 frontend/backend rolling pool 與 Edge 動態 upstream。
6. first deploy、一般 deploy、config-only deploy、rollback 必須是不同明確路徑。
7. 所有 live 操作前先在全新 Ubuntu 24.04 VM 的 staging inventory 演練。
## 2. 里程碑
### M0 - 文件、設定契約與安全邊界
- 建立 `deployment.yml.example` 與 Vault schema。
- 定義 host role、覆寫規則、WireGuard 自動配號、image tag 與目錄契約。
- 實作 `doctor`/`preflight`,拒絕缺 IP、重複 IP、DNS 未指向、SSH/sudo 不可用與 unsupported OS。
- 定義正式環境防火牆矩陣、Atlas 固定出口與 TLS 前置條件。
完成定義:不連線部署即可驗證完整設定;錯誤訊息能指出欄位與 host。
### M1 - 空 VM bootstrap
- 用 Ansible raw task 支援無 Python 的 Ubuntu 24.04。
- 安裝 Python、Docker/Compose、WireGuard、UFW、chrony、fail2ban、unattended-upgrades。
- 建立 `/opt/haixun`、`/etc/haixun`、`/var/lib/haixun`、服務帳號與權限。
- 設定 Docker log rotation、daemon 啟動、Registry trust/login hook。
- 防火牆先保留 SSH再按 role 套規則。
- bootstrap 可重跑,且不修改/清除 data volume。
完成定義:七種角色的空 VM 都可從只有 SSH/sudo 到 bootstrap ready第二次執行為 no-op 或安全更新。
### M2 - WireGuard、Registry 與本機 build pipeline
- 依 inventory 自動分配 WireGuard IP建立 peer 並驗證連通。
- 配置固定出口節點供 Atlas 連線。
- 部署帶 TLS/auth/persistent volume 的自架 Registry。
- Edge/Registry DNS 檢查與 Let's Encrypt 自動申請/續期。
- 新增 frontend/backend/worker/crawler/ops Dockerfile 與 Buildx build/push 指令。
- image 使用 git SHA保存上一個成功 tag 供 rollback。
完成定義:遠端 VM 不具備 source tree 也能 pull 並啟動測試 imageRegistry 重啟後 image 仍存在。
### M3 - Atlas、Redis、MinIO 與 first data initialization
- production 移除本機 Mongo 假設,所有 runtime 讀取 Atlas URI。
- Redis 獨立 Composeauth、AOF、volume、health、backup/restore。
- MinIO 獨立 Composevolume、health、bucket/policy idempotent init、backup/restore。
- ops image 提供 migration/init/seeder。
- seeder 改為由 Vault 設定 admin email/display name/password既有資料不覆寫。
- 將現有 backup、monitoring、reset 腳本從本機 Mongo 假設拆開Atlas 備份交由 Atlas Backup/PITR。
完成定義:空 Atlas database 可按 migration -> init -> seed 建立重跑不重複資料、不重設密碼Redis/MinIO restart 後資料保留。
### M4 - 應用角色拆分與無狀態修正
- frontend image 只含 production static build。
- backend image 含 gateway 與固定 extension ZIP path。
- worker image 含 Go worker、Node profile scraper、相容 Chromium。
- crawler sidecar 可設定 bind address、有 health endpoint只走 private Docker network。
- role-specific env/template 只下發所需 secret。
- gateway readiness 補 Mongo + Redisfrontend 提供 build versionworker 啟動檢查 identity/connectivity。
完成定義frontend/backend/worker 可分別 build、push、deploy、restart刪除任一 app container 後可從 image/config 重建且無業務資料遺失。
### M5 - 多節點、Edge 與一般部署
- Edge 依 inventory 產生 frontend/backend upstream。
- backend/frontend 採 `serial: 1` rolling recreatereadiness 後才加入流量。
- worker 支援指定 host 或整組新增/更新worker ID 唯一。
- config-only deploy 原子同步設定並只 recreate 指定角色。
- status/logs/restart/rollback 以 role/host 過濾。
- migration `run_once` 且先於 backend recreate失敗立即停止。
完成定義:增加一個 IP 可加入新 worker增加 frontend/backend IP 可健康註冊;部署期間其他健康節點持續服務。
### M6 - First deploy orchestrator、備份與演練
- `make first-deploy` 串接 M0-M5 checkpoint但每一步仍可單獨重跑。
- 建立 Redis/MinIO/Registry restore runbook 與 Atlas restore 責任邊界。
- 提供首次部署報告host、role、WG IP、image tag、health、TLS、backup 與單點警告。
- 在全新 staging VM 完成安裝、失敗續跑、config-only、加節點、rollback、重啟持久性與公網封鎖測試。
- live deployment 必須由使用者另行確認,不因完成程式碼而自動執行。
完成定義:從設定檔與空 VM 到完整 staging 可用,不登入遠端手動安裝或改設定。
## 3. 預計檔案落點
```text
apps/web/Dockerfile
apps/backend/Dockerfile.gateway
apps/backend/Dockerfile.worker
apps/backend/Dockerfile.ops
apps/backend/crawler/Dockerfile
deploy/prod/
Makefile
ansible.cfg
deployment.yml.example
secrets.vault.yml.example
inventory/
playbooks/
bootstrap.yml
first-deploy.yml
deploy.yml
database.yml
status.yml
roles/
common/
wireguard/
registry/
edge/
frontend/
backend/
worker/
redis/
minio/
templates/
scripts/
doctor.sh
preflight.sh
build.sh
push.sh
deploy.sh
```
現有單機 production scripts 在新流程驗收前不直接刪除;實作時先標示 legacy確認沒有現役依賴後再決定移除避免中斷既有環境。
## 4. 驗證矩陣
| ID | 驗證 |
|----|------|
| DEP-01 | 空 Ubuntu 24.04 無 Python VM 可 bootstrap |
| DEP-02 | bootstrap 重跑不清資料、不重建 secret |
| DEP-03 | 只填 SSH IP 即可自動配置 WireGuard IP |
| DEP-04 | Registry TLS/auth/persistence 正常 |
| DEP-05 | 應用 image 全由本機 build遠端無 source/build |
| DEP-06 | Atlas migration/init/seed 順序正確且可重跑 |
| DEP-07 | seed 不覆寫既有管理員密碼 |
| DEP-08 | Redis/MinIO restart 後資料保留 |
| DEP-09 | config-only deploy 不產生新 image且新設定生效 |
| DEP-10 | backend/frontend rolling deploy 保留健康服務 |
| DEP-11 | 新增 worker IP 後只有新 host 被 bootstrap/deploy |
| DEP-12 | 新增 backend/frontend 後 Edge 只加入健康節點 |
| DEP-13 | migration 失敗時 backend 保持舊版 |
| DEP-14 | rollback 可切回上一個成功 image tag |
| DEP-15 | 公網無法直連 Redis/MinIO private API/backend/crawler |
| DEP-16 | crawler sidecar 可用且 host 無公開 crawler port |
| DEP-17 | Atlas 連線顯示固定出口 IP |
| DEP-18 | 備份與還原演練有可驗證結果 |
## 5. 風險與後續
| 風險 | 第一版處理 |
|------|------------|
| Redis/MinIO/Registry/Edge 單點 | 明示風險、持久化、備份、restore runbookHA 後續里程碑 |
| 全 mesh 新增節點需更新 peers | 由 Ansible inventory 統一生成並分批套用 |
| Atlas 固定出口節點故障 | 第一版接受單點;文件化切換出口與 allowlist 流程 |
| Outbox 全域 lock 限制 worker 擴縮 | 部署不誤稱 Outbox 已水平擴充;另立應用 task 改 due query/claim/concurrency |
| 外部發文 at-least-once 重複 | 不在部署層假裝解決,保留既有 lease 風險並另案處理 |
| seeder 目前寫死管理員資料 | M3 先修成 Vault 可設定,再允許 first deploy seed |
| health 目前只檢查 Redis | M4 補 Mongo readiness避免壞節點進 upstream |
| 舊單機腳本仍可能在使用 | 新流程先並存並標 legacy不自動刪除或改動現役服務 |
## 6. 實作前仍需填入的實際值
- 所有 VM SSH IP、user、port、private key。
- Edge、Registry 網域與已完成的 DNS A/AAAA record。
- Atlas SRV URI、database user 與固定出口 allowlist。
- Registry、Redis、MinIO、JWT、加密、Crawler、Provider、SMTP 等 Vault secret。
- 初始管理員 email、display name、password。
- 各 VM CPU architecture、磁碟掛載與備份目的地。
上述值未備齊時可完成程式與 staging 測試,但不得執行正式 first deploy。