diff --git a/.agents/skills/01-awoooi-frontend-aesthetics.md b/.agents/skills/01-awoooi-frontend-aesthetics.md index eb2e9deb..b83d5ea0 100644 --- a/.agents/skills/01-awoooi-frontend-aesthetics.md +++ b/.agents/skills/01-awoooi-frontend-aesthetics.md @@ -25,6 +25,32 @@ | v1.2 | 2026-03-25 | Claude Code | 加入文件資訊區塊 | | v1.3 | 2026-03-27 | Claude Code | Phase 19 Z-Index/GenUI/快捷鍵規範 | | v1.4 | 2026-03-28 | Claude Code | ✅ Phase 19 Wave 0-5 完成 (~95% + Telemetry 整合) | +| v1.5 | 2026-03-30 | Claude Code | 🔴🔴🔴 前端建置禁止內網 IP (瀏覽器權限事故) | + +--- + +## 🔴🔴🔴 前端建置禁止內網 IP (2026-03-30) + +> **血的教訓**: CD 使用 `http://192.168.0.125:32334` 建置,導致瀏覽器彈出「存取區域網路」權限對話框 + +### 禁止清單 + +| 變數 | 禁止值 | 正確值 | +|------|--------|--------| +| `NEXT_PUBLIC_API_URL` | `http://192.168.0.*` | `https://awoooi.wooo.work` | +| `NEXT_PUBLIC_SENTRY_DSN` | 包含內網 IP | 使用 Sentry Tunnel | + +### 原理 + +`NEXT_PUBLIC_*` 是 **build-time** 變數,會被打包進 JS Bundle。Runtime 的 K8s ConfigMap 無法覆蓋。 + +### 檢查點 + +修改 CD Pipeline 時,必須確認: +```bash +grep "NEXT_PUBLIC" .gitea/workflows/cd.yaml | grep -v "192.168" +# 應該看到所有 NEXT_PUBLIC_* 都使用公網域名 +``` --- diff --git a/.agents/skills/04-awoooi-devops-commander.md b/.agents/skills/04-awoooi-devops-commander.md index 6c5ef345..7e722f35 100644 --- a/.agents/skills/04-awoooi-devops-commander.md +++ b/.agents/skills/04-awoooi-devops-commander.md @@ -31,6 +31,49 @@ | v1.8 | 2026-03-28 | Claude Code | **可觀測性端點配置規範 (SignOz 121→188 修正)** | | v1.9 | 2026-03-29 | Claude Code | **🔴 ADR-035 Telegram Secrets 自動注入鐵律** | | v2.0 | 2026-03-29 | Claude Code | **🆕 ArgoCD Metrics + TLS 證書監控 (P1/P2 改進)** | +| v2.1 | 2026-03-30 | Claude Code | **🔴🔴🔴 前端內網 IP 禁令 + CD 安全修復** | + +--- + +## 🔴🔴🔴 前端內網 IP 禁令 (2026-03-30) + +> **統帥指令**: CD Pipeline 建置 Web 映像時,`NEXT_PUBLIC_*` 禁止使用內網 IP +> **詳細文件**: `feedback_docker_nextjs_api_url.md` + `feedback_sentry_local_network.md` + +### 血的教訓 + +| 問題 | 後果 | 根因 | +|------|------|------| +| 瀏覽器權限對話框 | UX 極差,API 請求失敗 | `NEXT_PUBLIC_API_URL` 使用內網 IP | +| SSE 連線失敗 | Dashboard 無法更新 | build-time 變數寫死內網 IP | + +### CD Pipeline 建置規範 + +```yaml +# ❌ 絕對禁止 +--build-arg NEXT_PUBLIC_API_URL=http://192.168.0.125:32334 +--build-arg NEXT_PUBLIC_SENTRY_DSN=http://...@192.168.0.110:9000/2 + +# ✅ 必須使用公網域名 +--build-arg NEXT_PUBLIC_API_URL=https://awoooi.wooo.work +``` + +### 技術原理 + +| 變數類型 | 注入時機 | K8s ConfigMap 有效? | +|----------|---------|---------------------| +| `NEXT_PUBLIC_*` | **Build-time** | ❌ 無效 (已打包進 JS) | +| 一般環境變數 | Runtime | ✅ 有效 | + +### CD 安全規範 + +```yaml +# ❌ 禁止硬編碼密碼 +echo "0936223270" | sudo -S kubectl ... + +# ✅ 使用 Secret +echo "${{ secrets.SUDO_PASSWORD }}" | sudo -S kubectl ... +``` --- diff --git a/docs/adr/ADR-022-sentry-integration-architecture.md b/docs/adr/ADR-022-sentry-integration-architecture.md index b6f66290..b6a6d5f4 100644 --- a/docs/adr/ADR-022-sentry-integration-architecture.md +++ b/docs/adr/ADR-022-sentry-integration-architecture.md @@ -136,9 +136,39 @@ SENTRY_AUTH_TOKEN: str = "" # K8s Secret - 多一個服務需維護 (Sentry Self-Hosted) - 額外的 API 呼叫延遲 +## 🔴 前端內網 IP 禁令 (2026-03-30 補充) + +### 問題 + +前端 Sentry DSN 使用內網 IP (`192.168.0.110:9000`) 會觸發瀏覽器「存取區域網路」權限對話框。 + +### 解決方案 + +**已採用**: Sentry Tunnel (方案 A) + +``` +前端 → /api/sentry-tunnel → Sentry Server (192.168.0.110:9000) + ↑ 公網域名 ↑ Server-Side 內網 +``` + +**配置位置**: +- `apps/web/src/app/api/sentry-tunnel/route.ts` - Tunnel 實作 +- `apps/web/sentry.client.config.ts` - `tunnel: '/api/sentry-tunnel'` + +### CD Pipeline 規範 + +```yaml +# ❌ 禁止 (即使有 Tunnel,也不應暴露內網 IP) +--build-arg NEXT_PUBLIC_SENTRY_DSN=http://...@192.168.0.110:9000/2 + +# ✅ 不設定 (依賴 Tunnel 機制) +# 或使用公網域名反向代理 +``` + ## 相關文件 - `project_phase10_arch_review.md` - 架構審查報告 - `project_sentry_full_integration.md` - 整合計畫 +- `feedback_sentry_local_network.md` - 區域網路權限問題 - ADR-005: BFF Architecture - ADR-006: AI Fallback Strategy