# Requirements: 設定驅動的多主機正式部署

> Status: `draft-for-review`  
> Slug: `haixun-deployment`  
> Last updated: `2026-07-18`  
> Implementation: not started

## 1. 一句話

營運者只需在本機設定檔填寫主機 IP、網域與加密機密，就能把全新的 Ubuntu 24.04 VM 初始化並部署成可分開更新、重啟與擴充的 frontend、backend、worker、Redis、MinIO、Registry 與 Edge 環境。

## 2. 目標

### R-01 設定檔是部署真相來源

- 非機密拓撲集中在 `deploy/prod/deployment.yml`。
- 機密集中在 Ansible Vault 加密的 `deploy/prod/secrets.vault.yml`。
- 遠端不得成為設定真相來源，不要求登入遠端手動編輯 env 或 YAML。
- 每台主機最低只需填可 SSH 的 IP；SSH user/port/key 可設全域預設並允許單機覆寫。
- WireGuard IP 預設自動分配，必要時才手動覆寫。

### R-02 空 VM 可自動初始化

- 支援全新 Ubuntu 24.04 LTS VM。
- 初始前提僅為：SSH 可達、指定使用者可 `sudo`、DNS 已按設定指向 Edge 與 Registry。
- bootstrap 必須安裝 Python、Docker Engine、Compose plugin、WireGuard、UFW、chrony、fail2ban 與安全更新工具。
- bootstrap 必須建立服務帳號、目錄、權限、Docker log rotation、TLS 與防火牆規則。
- bootstrap 必須可重複執行且不得刪除既有資料。

### R-03 元件可獨立部署

- frontend、backend、worker、Redis、MinIO、Registry、Edge 可個別 bootstrap、deploy、restart、status 與 rollback（資料層 rollback 另定義）。
- frontend、backend、worker 不得綁在同一 release artifact。
- 本機 build image 並 push 至自架 Registry；遠端不得執行 Go/npm build。
- 遠端在舊服務仍運作時先 pull image，再以 Compose recreate/restart。
- 設定變更可不 rebuild image，單獨同步並 recreate 指定角色。

### R-04 可從設定動態增加節點

- frontend、backend、worker host list 可有任意多台。
- 新增 worker 後不需流量註冊即可開始 claim job，且每台 worker ID 必須唯一。
- 新增 frontend/backend 後，自動重建 Edge upstream；健康檢查通過後才加入流量。
- 同一部署指令只處理設定中指定的角色或 host，其他節點不得被意外重啟。

### R-05 資料與狀態

- MongoDB 使用 Atlas，不再於 production Compose 自架 MongoDB。
- Redis 第一版為獨立單機、啟用密碼與 AOF，接受單點故障。
- MinIO 第一版為獨立單機與持久 volume，接受單點故障。
- frontend/backend/worker container 應可替換；媒體物件持久化於 MinIO，業務資料持久化於 MongoDB，cache/lock 位於 Redis。
- worker 的 Playwright、Node script 與 Chromium 必須封裝在 image；解密 session 暫存檔只可位於 ephemeral storage 並限制權限。
- gateway 使用的 extension ZIP 必須封裝在固定 image path，不能依賴開發者本機絕對路徑。

### R-06 MongoDB Atlas 初始資料庫流程

- first deploy 必須先驗證 Atlas DNS、TLS、帳密、database name 與來源 allowlist。
- 依序執行 forward migration、`cmd/init`、`cmd/seeder`。
- migration 失敗不得切換 backend。
- `cmd/init` 必須保持 idempotent，僅建立 operational indexes。
- seeder 的管理員 email、display name、password 必須由 Vault 設定。
- 重跑 seeder 不得覆寫既有管理員密碼；改密碼必須是獨立明確操作。
- 一般 deploy 可執行 migration，但不得每次自動 seed。

### R-07 網路與安全

- 主機間服務流量走 WireGuard，不直接暴露 Redis、MinIO、backend 或 crawler 到公網。
- Edge 僅公開網站需要的 `80/443`；Registry 只以 TLS 提供服務並要求認證。
- Edge 與 Registry 使用 DNS + Let's Encrypt，憑證自動續期。
- Atlas 只 allowlist 固定出口 IP；backend/worker 的 Atlas 流量必須符合此出口設計。
- frontend 與 API 使用同網域，Edge 將 `/api` 轉送 backend，將 `/haixun-assets` 轉送 MinIO。
- crawler 只能在 worker Docker private network 內被存取，不 publish host port。
- Vault 明文、生成的 env、Registry 密碼與私鑰不得提交 Git 或寫入 image。

### R-08 維運與防呆

- 提供 preflight、doctor、status、logs、restart、deploy-config 與 rollback 指令。
- 所有設定先寫暫存檔並驗證，再原子替換。
- backend/frontend 採健康節點逐台更新，不可一次停止所有副本。
- destructive reset/wipe 不得包含在一般 deploy，且必須有環境名稱與二次確認。
- Redis、MinIO 與 Registry 必須具備備份與還原文件；Atlas 備份使用 Atlas Backup/PITR。
- 單機 Redis、MinIO、Registry、Edge 的單點風險必須在 status 與文件中明示。

## 3. 不在第一版範圍

- Kubernetes。
- Docker Swarm。
- Redis Sentinel/Cluster。
- 分散式 MinIO。
- 多 Edge 高可用與自動 failover。
- 在遠端 VM 進行應用程式編譯。
- 自動建立 MongoDB Atlas project/cluster；第一版只連接已建立的 Atlas cluster。
- 自動修改 Atlas allowlist；固定出口 IP 先由營運者配置到 Atlas。

## 4. 已知限制

- 增加 worker 可提高一般 Mongo job 吞吐量，但目前 Outbox 仍被全域 Redis lock 序列化。
- Outbox 查詢目前最多掃描 500 筆且不適合作為大規模 worker pool 的最終方案。
- Redis、MinIO、Registry、Edge 第一版各一台時仍有單點故障。
- gateway 現有 health endpoint 只檢查 Redis；正式 rolling deployment 前需補足 Mongo readiness。

## 5. 驗收摘要

- 從全新 Ubuntu 24.04 VM 開始，除 DNS/Atlas/SSH 外不需登入遠端手動操作。
- 修改一份 host 設定加入 worker IP 後，可只部署新 worker。
- 修改設定但不 build，遠端 recreate 後能讀到新設定。
- backend/frontend 多節點更新期間至少保留一個健康節點。
- migration/init/seed 的順序、失敗停止與重跑安全性可驗證。
- 公網不能直連 Redis、MinIO private API、backend private port 或 crawler。
