2026-06-29 16:11:08 +00:00
|
|
|
|
# 巡樓部署 (infra)
|
|
|
|
|
|
|
|
|
|
|
|
部署拓樸:
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
瀏覽器 → nginx(systemd, :80/:443)
|
|
|
|
|
|
├─ 靜態前端 /var/www/haixun (frontend/dist)
|
|
|
|
|
|
└─ /api 反向代理 → Go gateway (systemd, 127.0.0.1:8890)
|
|
|
|
|
|
Go gateway / Go worker (systemd) → Mongo / Redis (docker compose, 綁 127.0.0.1)
|
|
|
|
|
|
Node playwright worker (systemd) → 透過 HTTP 打 gateway
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
- 資料服務(Mongo/Redis)用 docker compose,只綁 `127.0.0.1`。
|
|
|
|
|
|
- Go gateway / Go worker / Node worker 都是 systemd 原生服務。
|
|
|
|
|
|
- secret 一律放 `/opt/haixun/etc/haixun.env`(不進 repo),yaml 用 `${VAR}` 讀取。
|
|
|
|
|
|
|
|
|
|
|
|
## 目錄
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
infra/
|
|
|
|
|
|
docker-compose.yml # mongo + redis
|
|
|
|
|
|
etc/haixun.env.example # systemd EnvironmentFile 範本(secret)
|
2026-07-06 06:13:14 +00:00
|
|
|
|
nginx/haixun.conf # 正式環境(靜態檔 + /api)
|
|
|
|
|
|
nginx/haixun-dev.conf # 開發環境(Vite 前端 proxy + /api)
|
2026-06-29 16:11:08 +00:00
|
|
|
|
systemd/
|
|
|
|
|
|
haixun-gateway.service
|
|
|
|
|
|
haixun-worker.service
|
|
|
|
|
|
haixun-node-worker.service
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-07-06 06:13:14 +00:00
|
|
|
|
> compose 的 env 一律從 `deploy/.env.dev`(dev)或 `deploy/.env.prod`(prod)讀,infra 本身不再放 `.env`。
|
|
|
|
|
|
|
2026-06-29 16:11:08 +00:00
|
|
|
|
## 1. 起資料服務 (docker)
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
2026-07-06 06:13:14 +00:00
|
|
|
|
make dev-infra # 讀 deploy/.env.dev
|
|
|
|
|
|
docker compose --env-file deploy/.env.dev -f infra/docker-compose.yml ps
|
2026-06-29 16:11:08 +00:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 2. 建置產物(本機或 CI)
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
make build # 前端 dist + 兩個 linux Go binary(backend/bin/)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 3. 安裝到目標主機
|
|
|
|
|
|
|
|
|
|
|
|
於目標主機(需 root):
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
sudo make install
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
`make install` 會:
|
|
|
|
|
|
|
|
|
|
|
|
1. 建立使用者 `haixun` 與目錄 `/opt/haixun/{bin,etc,node-worker}`、`/var/www/haixun`。
|
|
|
|
|
|
2. 複製 `backend/bin/{gateway,worker}`、`backend/etc/gateway.prod.yaml`、`backend/etc/gateway.worker.prod.yaml`。
|
|
|
|
|
|
3. 複製 `frontend/dist/*` → `/var/www/haixun`。
|
|
|
|
|
|
4. 複製 `backend/worker/*`(Node worker)→ `/opt/haixun/node-worker`,並 `npm ci` + `npx playwright install`。
|
|
|
|
|
|
5. 安裝 `infra/systemd/*.service` 與 `infra/nginx/haixun.conf`。
|
|
|
|
|
|
|
|
|
|
|
|
接著手動建立 secret 檔(**只做一次**):
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
sudo cp infra/etc/haixun.env.example /opt/haixun/etc/haixun.env
|
|
|
|
|
|
sudo chmod 600 /opt/haixun/etc/haixun.env
|
|
|
|
|
|
sudoedit /opt/haixun/etc/haixun.env # 填入實際 secret
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 4. 初始化資料庫與 admin 帳號(只做一次)
|
|
|
|
|
|
|
|
|
|
|
|
Mongo 起來、secret 填好後,建立索引 / 權限 catalog / role_permissions,並建立第一個 admin:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 可在 haixun.env 內設定 INIT_ADMIN_EMAIL / INIT_ADMIN_PASSWORD,或在這裡用環境變數覆寫
|
|
|
|
|
|
sudo make prod-init
|
|
|
|
|
|
# 等同:source /opt/haixun/etc/haixun.env 後執行 /opt/haixun/bin/tool init -f /opt/haixun/etc/gateway.prod.yaml
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
之後一般使用者可走 `POST /api/v1/auth/register` 自助註冊(前端登入頁)。
|
|
|
|
|
|
|
|
|
|
|
|
## 5. 啟用服務
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
sudo systemctl daemon-reload
|
|
|
|
|
|
sudo systemctl enable --now haixun-gateway haixun-worker haixun-node-worker
|
|
|
|
|
|
sudo nginx -t && sudo systemctl reload nginx
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 6. 健康檢查
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
curl http://127.0.0.1:8890/api/v1/health
|
|
|
|
|
|
sudo systemctl status haixun-gateway haixun-worker haixun-node-worker
|
|
|
|
|
|
journalctl -u haixun-gateway -f
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 產生 secret
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
openssl rand -base64 48 # JWT access / refresh / worker secret
|
|
|
|
|
|
openssl rand -base64 32 # HAIXUN_SECRETS_KEY(機敏資料落地加密)
|
|
|
|
|
|
```
|
2026-07-06 06:13:14 +00:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 本地開發使用 nginx 反向代理(推薦搭配 https 網域)
|
|
|
|
|
|
|
|
|
|
|
|
當你用 `make run` + `make web-dev` 直接啟動前後端時,建議再加一層 nginx 來:
|
|
|
|
|
|
|
|
|
|
|
|
- 用正式網域名稱 `https://threads-tool.30cm.net` 存取
|
|
|
|
|
|
- 自動處理 http → https 轉址
|
|
|
|
|
|
- `/` 給前端 Vite(含 HMR websocket)
|
|
|
|
|
|
- `/api/` 給後端(正確處理 SSE 串流)
|
|
|
|
|
|
|
|
|
|
|
|
### 步驟
|
|
|
|
|
|
|
|
|
|
|
|
1. 確認前後端已在跑:
|
|
|
|
|
|
```bash
|
|
|
|
|
|
make run # 後端 8890
|
|
|
|
|
|
make web-dev # 前端 5173
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
2. 準備 SSL 憑證(強烈建議):
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 安裝 certbot(Ubuntu/Debian 範例)
|
|
|
|
|
|
sudo apt install certbot python3-certbot-nginx
|
|
|
|
|
|
sudo certbot --nginx -d threads-tool.30cm.net
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
3. 啟用開發版 nginx 設定:
|
|
|
|
|
|
```bash
|
|
|
|
|
|
sudo cp infra/nginx/haixun-dev.conf /etc/nginx/conf.d/haixun.conf
|
|
|
|
|
|
# 或傳統 sites-available 方式
|
|
|
|
|
|
# sudo ln -s ... /etc/nginx/sites-enabled/
|
|
|
|
|
|
|
|
|
|
|
|
sudo nginx -t
|
|
|
|
|
|
sudo systemctl reload nginx
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
4. 存取測試:
|
|
|
|
|
|
- https://threads-tool.30cm.net ← 前端
|
|
|
|
|
|
- https://threads-tool.30cm.net/api/v1/health ← 後端
|
|
|
|
|
|
|
|
|
|
|
|
### 重要設定說明(haixun-dev.conf 內)
|
|
|
|
|
|
|
|
|
|
|
|
- `upstream haixun_frontend` → 127.0.0.1:5173
|
|
|
|
|
|
- `upstream haixun_backend` → 127.0.0.1:8890
|
|
|
|
|
|
- `/api/` location 已開啟完整 SSE 長連線設定(proxy_buffering off 等)
|
|
|
|
|
|
- `/` location 已加上 `Upgrade` + `Connection` 讓 Vite HMR 正常運作
|
|
|
|
|
|
- 預設會把 http 301 轉 https
|
|
|
|
|
|
- SSL 路徑預設為 Let's Encrypt(certbot 會自動產生)
|
|
|
|
|
|
|
|
|
|
|
|
### 切回正式版
|
|
|
|
|
|
|
|
|
|
|
|
部署正式靜態檔後,換回原本的設定:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
sudo cp infra/nginx/haixun.conf /etc/nginx/conf.d/haixun.conf
|
|
|
|
|
|
sudo nginx -t && sudo systemctl reload nginx
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 常見問題
|
|
|
|
|
|
|
|
|
|
|
|
- **HMR 不更新**:檢查 nginx location / 有沒有 `proxy_set_header Upgrade` 和 `Connection "upgrade"`
|
|
|
|
|
|
- **API 串流斷掉**:確認 `/api/` location 有 `proxy_buffering off; proxy_read_timeout 3600s;`
|
|
|
|
|
|
- **憑證錯誤**:先用 `curl -k` 測試,或暫時註解 return 301 那行用 http 測試
|
|
|
|
|
|
- **權限問題**:nginx 需能連 127.0.0.1:5173 / :8890(通常沒問題)
|
|
|
|
|
|
- **想同時支援 IP 直接存取**:在 server_name 後面加上 `10.0.0.5;` 或 `_`
|
|
|
|
|
|
|
|
|
|
|
|
開發時用這個 dev conf 就很夠了,之後正式上線再切回靜態檔版本。
|