Files
ewoooc/CLAUDE.md
ogt 1b4f3a7bbe
Some checks failed
CD Pipeline / deploy (push) Failing after 59s
feat: EwoooC 初始化 — 完整專案推版至 Gitea
- 建立 Gitea Actions CD pipeline (.gitea/workflows/cd.yaml)
- 部署模式: rsync Python 檔案至 188 → docker restart (volume mount)
- Dockerfile/requirements 變動時自動重建 Docker image
- 部署通知: Telegram (開始/成功/失敗)
- 健康檢查: https://mo.wooo.work/health (最多 5 次重試)
- 同步最新 CLAUDE.md / ADR-008 / memory (2026-04-19)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 01:21:13 +08:00

188 KiB
Raw Blame History

EwoooC — Claude 專案記憶(原 MOMO Pro System

此檔案供 Claude Code 自動讀取,記錄專案的關鍵資訊與待辦事項。 專案正式名稱EwoooCADR-0062026-04-18 決策) 範圍:本目錄唯一範圍為 momo-pro-system不含 AWOOOI / WOOO AIOps SaaS


🏛️ 第零章遊戲規則憲法Claude Code 官方規範 — 2026-04-18 訂立)

這是本系統的元憲法。所有 AI 助手Claude / Antigravity在任何 Session 開始前必須先讀此章。

📐 記憶架構分層(四層缺一不可)

層次 位置 用途 生命週期
Memory持久記憶 ~/.claude/projects/.../memory/*.md 統帥偏好、技術決策、協作 context 永久,跨 Session
ADR架構決策記錄 docs/adr/ADR-XXX-*.md 重大架構決策,含背景/替代方案/後果 永久,只增不刪
SOT單一事實來源 docs/AI_INTELLIGENCE_MODULE_SOT.md 當前 AI 模組架構狀態(可更新) 隨架構演進
Skills執行流程 .claude/skills/*.py Claude 執行複雜任務的 SOP checklist 隨流程成熟迭代

📋 失憶防範三大鐵律(絕對禁止違反)

鐵律一:每次決策必沉澱

  • 任何架構決策 → 立刻建 ADR-XXX.md + 更新 docs/adr/README.md
  • 任何統帥偏好/風格 → 立刻寫入 memory/user_profile.md 或新 memory 文件
  • 任何技術債/待辦 → 立刻寫入 memory/project_tech_debt_backlog.md
  • 禁止:口頭決定不留文字記錄(下個 Session 必失憶)

鐵律二CLAUDE.md 是憲法主幹

  • 每次 Session 開始,先讀 CLAUDE.md → memory/ → 相關 ADR
  • 重大架構章節必須同步更新到 CLAUDE.mdSOT 章節)
  • 新憲法條款必須更新 CONSTITUTION.md
  • 禁止:依賴 Claude 對話 Session 記憶context window 有截斷)

鐵律三:範圍邊界

  • 本 CLAUDE.md 範圍 = Momo Pro SystemEwoooC唯一
  • 禁止:將 AWOOOI / WOOO AIOps SaaS 的決策混入本文件
  • 禁止:跨專案邊界做架構決策

🔄 Session 開始 SOP每次 Claude 啟動必做)

1. 讀 CLAUDE.md 頭部(此章 + 環境章)
2. 讀 memory/MEMORY.md 索引 → 依需求讀具體 memory
3. 讀 docs/adr/README.md 索引 → 依任務讀相關 ADR
4. 確認當前任務屬於哪個 Agent 層Hermes/NemoTron/OpenClaw
5. 確認任務結束後需更新哪些記憶層

📝 記憶更新 SOP每次 Session 結束前必做)

□ 有架構決策?→ 新建或更新 docs/adr/ADR-XXX.md + README.md 索引
□ 有統帥偏好/回饋?→ 更新 memory/user_profile.md 或 feedback_*.md
□ 有技術債?→ 更新 memory/project_tech_debt_backlog.md
□ 有 SOT 變更?→ 更新 docs/AI_INTELLIGENCE_MODULE_SOT.md
□ 有憲法新條款?→ 更新 CONSTITUTION.md + 本 CLAUDE.md
□ 有技能流程變更?→ 更新 .claude/skills/ 對應 skill 文件
□ 更新 memory/MEMORY.md 索引(加入新 memory 文件連結)

專案概覽

項目 說明
專案名稱 EwoooC原 MOMO Pro SystemWOOO TECH
技術棧 Flask (gunicorn) + PostgreSQL (pgvector) + Docker Compose V12.0
主要功能 商品看板、每日業績報表、廠商缺貨通知、EDM 爬蟲、AI 知識庫(KM)
正式運行主機 ollama@192.168.0.188Docker Compose非 K8s
對外域名 mo.wooo.work / momo.wooo.work(皆透過 110 VM Nginx 反向代理)

🌐 環境架構總覽2026-04-19 依 SSH 實地審計重寫,見 ADR-008

重要: 先前文件誤記為「K3s / kubectl / 192.168.0.110 運行應用」。實地審計 (2026-04-18) 確認 EwoooC 從未遷移到 K8s188 始終是 Docker Compose 架構。本章以實際現況為準。

主機 角色 承載內容
192.168.0.188 (ollama@) EwoooC 正式運行主機 momo-pro-system / momo-db / momo-scheduler / openclaw / n8n(Docker) / Ollama
192.168.0.110 (wooo@) 周邊服務主機 VM Nginx 反向代理、Harbor(仍在運行)、Sentry self-hosted、SigNoz、Gitea (+ runner)、Langfuse、監控 exporter
192.168.0.112 (kali@) 安全掃描工作站 Nmap / Bandit / Trivy / WireGuard

⚠️ 110 的 /home/wooo/momo_pro_system/ 實際已空置(僅剩 docker/ + venv/),不是 EwoooC 的運行目錄。 ⚠️ 110 載載 load avg ≈ 14.5,負責 monitor.wooo.work / registry.wooo.work / Harbor / Sentry / SigNoz 等周邊堆疊。

EwoooC 運行主機細節(ollama@192.168.0.188

項目
專案路徑 /home/ollama/momo-pro/
部署方式 Docker Compose V12.0(無 Git 版控,純檔案系統)
主容器 momo-pro-system (Flask + gunicorn) / momo-db (pgvector/pgvector:pg14) / momo-scheduler / openclaw (clawbot-v5)
容器啟動指令 gunicorn --bind 0.0.0.0:80 --workers 4 --timeout 300 app:app
主容器端口 127.0.0.1:5003:80gunicorn 內部聽 80host 僅本地 5003
Volume 掛載 app.py / scheduler.py / config.py / auth.py / config/ / database/ / templates/ / services/ / routes/ / data/ / logs/ / backups/(皆為 host 目錄掛到容器 /app,修改即時生效)
未掛載 docs/CLAUDE.md / ADR 純屬本地參考文件)
資料庫 momo-db 使用 pgvector/pgvector:pg14,為 AI KM 模組ADR-002/003/007提供 vector(1024) 欄位

SSH 連線 SOP必須經 110 跳板)

# 先跳 110
ssh wooo@192.168.0.110
# 再進 188SSH Key 已預先建立)
ssh ollama@192.168.0.188

Claude 工具層可直接執行:ssh -J wooo@192.168.0.110 ollama@192.168.0.188 "<cmd>"

Docker Compose 管理指令(在 188 上)

cd /home/ollama/momo-pro

# 查看所有容器
docker ps

# 即時日誌Flask 主應用)
docker logs -f momo-pro-system --tail 100

# 重啟主應用Python 檔案 volume 掛載已更新時使用)
docker restart momo-pro-system

# 完全重建(新增 Python 套件/更改 Dockerfile 時)
docker compose build momo-app && docker compose up -d momo-app

# 進入資料庫
docker exec -it momo-db psql -U momo -d momo_analytics

網路架構圖2026-04-19 實地重繪)

                              ┌────────────────────────────────────────────────┐
  Internet                    │       110 (wooo@192.168.0.110)                 │
     │                        │       周邊服務主機 + VM Nginx 反向代理            │
     ▼                        │                                                │
  ┌──────────┐                │  VM Nginx (systemd, port 80/443, SSL)          │
  │ DNS      │                │    ├─ mo.wooo.work      ──┐                    │
  │ Records  │                │    ├─ momo.wooo.work    ──┤  ⚠️ TODO:需統帥確認 │
  └────┬─────┘                │    ├─ registry.wooo.work ─┤  這兩個域名目前     │
       │                      │    ├─ monitor.wooo.work   │  實際 upstream 為何?│
       ▼                      │    └─ ollama.wooo.work   ─┘  檔案 /etc/nginx/   │
  ┌──────────┐                │                              sites-enabled/momo│
  │DNS → 110 │                │  (110 本地的周邊容器:)                          │
  └────┬─────┘                │    Harbor (11 個 harbor-* 容器,仍在運行)        │
       │                      │    Sentry self-hosted (30+ 容器)               │
       │                      │    SigNoz / Gitea + runner / Langfuse          │
       │                      │    Docker Registry / Superset                  │
       │                      │    Prometheus exporters / Fail2Ban exporter    │
       │ (VM Nginx 反向代理)   └────────────────────────────┬───────────────────┘
       │                                                    │  (proxy_pass)
       ▼                                                    ▼
  ┌────────────────────────────────────────────────────────────────────┐
  │            188 (ollama@192.168.0.188)  EwoooC 正式運行主機          │
  │               /home/ollama/momo-pro/  (Docker Compose V12.0)       │
  ├────────────────────────────────────────────────────────────────────┤
  │                                                                    │
  │  ┌────────────────────┐   ┌───────────────────┐                    │
  │  │ momo-pro-system    │──▶│  momo-db          │                    │
  │  │ Flask + gunicorn   │   │  pgvector/pg14    │                    │
  │  │ 127.0.0.1:5003:80  │   │  (DB + KM vector) │                    │
  │  └────────────────────┘   └───────────────────┘                    │
  │  ┌────────────────────┐   ┌───────────────────┐                    │
  │  │ momo-scheduler     │   │ openclaw          │                    │
  │  │ (爬蟲排程)          │   │ (clawbot-v5)      │                    │
  │  └────────────────────┘   └───────────────────┘                    │
  │  ┌────────────────────┐   ┌───────────────────┐                    │
  │  │ n8n (Docker)       │   │ Ollama + WebUI    │                    │
  │  └────────────────────┘   └───────────────────┘                    │
  └────────────────────────────────────────────────────────────────────┘

服務端口對照表

服務 主機 類型 本地綁定 外部訪問 說明
momo-pro-system 188 Docker 127.0.0.1:5003:80 mo.wooo.work / momo.wooo.work (經 110 VM Nginx) Flask + gunicorn (4 workers)
momo-db 188 Docker 內部 network 僅容器網路 pgvector/pg14
momo-scheduler 188 Docker 爬蟲排程
openclaw 188 Docker clawbot-v5
n8n 188 Docker 127.0.0.1:5678:5678 monitor.wooo.work/n8n/ (經 110 代理) Webhook 自動化
Ollama 188 Docker 內部 network ollama.wooo.work (經 110) AI 模型服務
Registry 110 Docker 127.0.0.1:5000 registry.wooo.work (經 VM Nginx) Container Registry
Prometheus 110 Docker 內部 monitor.wooo.work/prometheus/ 監控指標收集
Grafana 110 Docker 內部 monitor.wooo.work/grafana/ 監控儀表板
Alertmanager 110 Docker 內部 monitor.wooo.work/alertmanager/ 告警路由
Harbor 110 Docker 內部 待定 尚未撤除(文件先前誤報已移除)

VM Nginx 反向代理110 上)

Nginx 配置位置:/etc/nginx/sites-enabled/momo

mo.wooo.work / momo.wooo.work 的流量路徑(現況推測,待驗證):

用戶 → {mo|momo}.wooo.work:443 → 110 VM Nginx (SSL 終結) → ??? → 188:5003 momo-pro-system

⚠️ TODO: 需統帥確認 — 110 上 proxy_pass 的具體 upstream。若為 http://192.168.0.188:5003,要求 188 的 5003 對 110 開放(非純 127.0.0.1 綁定);若 110 本機另跑一個 reverse proxy daemon 聽 127.0.0.1:5001 再轉 188需補查。此段待 SSH 到 110 檢視 sites-enabled/momo 實際內容後更新。

監控堆疊Docker分佈於 110 + 188

組件 主機 說明
Prometheus 110 Docker 抓取 110 + 188 兩邊的 exporter
Grafana 110 Docker monitor.wooo.work/grafana/
Alertmanager 110 Docker 告警 → Telegram
Node Exporter 110 + 188 各自主機指標
cAdvisor 110 + 188 容器資源指標
n8n 188 Docker 自動化 Webhook容器名 n8n

Grafana 登入:

  • URL: http://192.168.0.110:30030(若已改內部綁定,需透過 monitor.wooo.work
  • 帳號 / 密碼: admin / Wooo_Grafana_2026

Telegram 告警配置:

  • Bot: @wooowooowooobot
  • Chat ID: 5619078117

故障排除:服務 502 / 容器停止

K3s / kubectl / PVC / StatefulSet 相關故障排除流程已作廢188 無 K8s。改用 Docker Compose 操作:

# 在 188 上
docker ps -a | grep momo                      # 查看容器狀態
docker logs -f momo-pro-system --tail 100     # 看日誌
docker restart momo-pro-system                # 單純重啟
cd /home/ollama/momo-pro && docker compose up -d  # 全部重新拉起

# 在 110 上VM Nginx 若異常)
sudo systemctl reload nginx
sudo nginx -t

回滾Docker Compose 原生機制)

188 無 K8s,無所謂「回滾到 Docker Compose」。版本回退方式是

  1. 重建 Docker image 至舊版本並 docker compose up -d
  2. 若 Python 檔案損壞,可從 /home/ollama/momo-pro/backups/ 取回

過往 /home/wooo/backups/pre-k8s-migration/quick_rollback.sh 已失去意義188 從未 K8s 化),保留檔案但不再作為回滾途徑。


🔐 服務帳號密碼總覽 (2026-04-18 更新)

單一監控中心: 所有服務集中於 UAT 主機

應用服務

環境 服務 URL 帳號 密碼 版本
🟢 正式 EwoooCMOMO Pro https://mo.wooo.work、https://momo.wooo.work - 0936223270 V9.4Docker Compose 於 188
🟢 正式 CI/CD Dashboard https://mo.wooo.work/cicd - - -
🟢 正式 PostgreSQL (momo-db, pgvector) 容器內部 network on 188 momo wooo_pg_2026 pgvector/pg14含 KM vector(1024)

監控服務 (集中於 UAT)

服務 URL 帳號 密碼 說明
監控入口頁面 https://monitor.wooo.work/ - - 所有監控服務入口 (110)
Grafana http://192.168.0.110:30030 或 monitor.wooo.work/grafana/ admin Wooo_Grafana_2026 監控儀表板 (110 Docker)
Prometheus monitor.wooo.work/prometheus/ - - 指標收集 (110 Docker)
Alertmanager monitor.wooo.work/alertmanager/ - - 告警路由 → Telegram (110 Docker)
n8n http://192.168.0.188:5678 (內部) admin@wooo.work Wooo_N8n_2026 自動化工作流程 (188 Docker, 容器名 n8n)

開發工具

服務 URL 帳號 密碼 說明
Registry https://registry.wooo.work admin Wooo_Registry_2026 Container Registry

BI 分析平台

服務 URL 帳號 密碼 說明
Apache Superset https://monitor.wooo.work/superset/ admin Wooo_Superset_2026 BI 分析儀表板
Superset DB (readonly) 10.42.0.199:5432 superset_readonly Wooo_Superset_RO_2026 唯讀資料庫用戶

管理工具

服務 URL 帳號 密碼 說明
Portainer https://monitor.wooo.work/portainer/ admin Wooo_Portainer_2026 Docker 容器管理

AI 服務

服務 URL API Key 說明
Ollama AI https://ollama.wooo.work 0df8b4f247a4497998248f013ce92a17 AI 模型服務
Gemini AI API AIzaSyCqv7TY2iTGi2wa91d2irwH08VYXjT9YUk 文案生成

指標收集器 (Exporters)

服務 URL 說明
Node Exporter 110 + 188 (127.0.0.1:9100) 各主機 CPU/記憶體/磁碟
cAdvisor 110 + 188 (127.0.0.1:8080) 容器資源使用
Postgres Exporter 188 Docker (針對 momo-db pgvector) PostgreSQL 監控
Blackbox Exporter 110 (127.0.0.1:9115) 外部服務探測

SSH 連線

伺服器 指令 密碼 說明
EwoooC 正式主機 ssh -J wooo@192.168.0.110 ollama@192.168.0.188 0936223270 運行 Flask 主應用 / momo-db / scheduler / openclaw / n8n / Ollama
周邊服務主機 ssh wooo@192.168.0.110 0936223270 VM Nginx 反代 / Harbor / Sentry / SigNoz / Gitea / 監控堆疊
Kali DevSecOps ssh kali@192.168.0.112 - 安全掃描工作站

Telegram 告警

項目
Bot Token 8075645931:AAH-EGKMo8ZC4QJs-Nc1_0s92xHrGdQvdpg
Chat ID 5619078117
告警來源 Alertmanager + n8n 工作流程
告警類型 Pod OOMKilled、重啟過多、記憶體不足等

API Keys 總覽

服務 Key 用途
Gemini AI AIzaSyCqv7TY2iTGi2wa91d2irwH08VYXjT9YUk Google Gemini AI 文案生成
YouTube API AIzaSyBA9n7-rYIQVMq8rSF7kz486avBAfFzJ0s YouTube 趨勢爬蟲
n8n API wooo_n8n_api_2026 n8n 工作流 API 存取
Ollama API 0df8b4f247a4497998248f013ce92a17.vqSWDEK0RppTZIwcdT-ei-Sz Ollama AI 模型服務
LINE Channel nD6MSXjB2FyB111zpT6Yik5B275mi6olHjjf94VnqN1ljUcqzcA7KtSSslxsOCEG6pERzmidNJFdzol6h+9V+t1x3j4Q8ljAacqC+i0627RuwbkiLxoHTJ/9HbIdehhoSJoeuNJHLraE721iDDfIuQdB04t89/1O/w1cDnyilFU= LINE 訊息推送
Telegram Bot 8075645931:AAH-EGKMo8ZC4QJs-Nc1_0s92xHrGdQvdpg Telegram 告警通知

🔄 運維架構2026-04-19 依 SSH 實地審計重寫)

架構: EwoooC 正式服務跑在 188 Docker Compose,監控告警堆疊跑在 110 Docker,n8n Webhook 引擎跑在 188 Docker (容器名 n8n)。

架構圖

┌──────────────────────────────────────────────┐    ┌─────────────────────────────────────────────┐
│  110 (wooo@192.168.0.110) 周邊服務主機          │    │ 188 (ollama@192.168.0.188) EwoooC 正式主機    │
│                                              │    │                                             │
│  ┌────────────────────────────────────────┐  │    │  ┌───────────────────────────────────────┐  │
│  │ Prometheus + Grafana + Alertmanager    │  │    │  │  /home/ollama/momo-pro/ (Compose V12)  │  │
│  │ (Docker)                               │──┼────┼─▶│  momo-pro-system / momo-db (pgvector) │  │
│  │  每 15s 抓取 110 + 188 exporter 指標    │  │    │  │  momo-scheduler / openclaw / n8n      │  │
│  └────────────────────────────────────────┘  │    │  └───────────────────────────────────────┘  │
│  ┌────────────────────────────────────────┐  │    │  ┌───────────────────────────────────────┐  │
│  │ VM Nginx (systemd) SSL 終結 + 反代     │──┼────┼─▶│  127.0.0.1:5003 momo-pro-system       │  │
│  │  mo.wooo.work / momo.wooo.work → 188   │  │    │  │  (⚠️ TODO 待確認 5003 對 110 開放路徑) │  │
│  └────────────────────────────────────────┘  │    │  └───────────────────────────────────────┘  │
│                                              │    │  ┌───────────────────────────────────────┐  │
│  Harbor / Sentry / SigNoz / Gitea / Langfuse │    │  │  n8n Docker (容器名 `n8n`)             │  │
│  Docker Registry / Superset                  │    │  │  自動化工作流程引擎                     │  │
│  (monitor.wooo.work 反代入口)                 │    │  └───────────────────────────────────────┘  │
└──────────────────────────────────────────────┘    └─────────────────────────────────────────────┘

監控 → 告警 → 自動修復 流程

Prometheus(110) 每 15s 抓取
    │
    ├─ 110 cAdvisor/Node exporter
    ├─ 188 cAdvisor/Node exporter
    ├─ momo-db pg_exporter (188)
    └─ Blackbox: mo.wooo.work / momo.wooo.work / monitor.wooo.work
                        │
                        ▼
                 Alertmanager(110) 告警路由
                        │
                        ├─ Telegram 通知(@wooowooowooobot
                        └─ n8n webhook 觸發自動修復
                                │
                                ▼
                          ssh 188 → docker restart <container>

域名健康監控腳本2026-02-09 / 2026-04-19 修正)

腳本位置: /home/wooo/scripts/domain-health-monitor.sh110 上執行,因為 110 是 VM Nginx 所在,也能 SSH 到 188 Cron 排程: 每 5 分鐘執行

監控域名清單:

域名 預期狀態碼 服務名稱 自動修復命令
https://mo.wooo.work/health 200 EwoooC App (正式) ssh ollama@188 "docker restart momo-pro-system"
https://momo.wooo.work/health 200 EwoooC App (momo 域名別名) ssh ollama@188 "docker restart momo-pro-system"
https://monitor.wooo.work/ 200 Monitor 首頁 (110) sudo systemctl reload nginx
https://registry.wooo.work/v2/ 401 Docker Registry (110) cd /home/wooo/devops/registry && docker compose restart
http://192.168.0.188:5678/ 200 n8n (188) ssh ollama@188 "docker restart n8n"
https://monitor.wooo.work/superset/login/ 200 Superset (110) docker compose restart

Cron 設定:

*/5 * * * * /home/wooo/scripts/domain-health-monitor.sh >> /home/wooo/logs/domain_health_monitor.log 2>&1

日誌檔案: /home/wooo/logs/domain_health_monitor.log

基礎設施清單

項目 主機 狀態 備註
Docker Compose 188 V12.0 承載 EwoooC 正式服務
pgvector DB 188 Docker pg14 AI KM vector(1024)
Prometheus 110 Docker 指標收集
Grafana 110 Docker 儀表板
Alertmanager 110 Docker Telegram 告警
n8n 188 Docker 容器名 n8n,自動化任務
PostgreSQL Exporter 188 Docker 對 momo-db 做指標
自動修復 110 Cron domain-health-monitor.sh via SSH

n8n 自動化工作流程 (2026-02-07 更新)

概述

n8n 作為 UAT 監控管理平台,負責:

  • UAT 服務監控與自動修復
  • 系統告警通知 (Telegram)
類型 Python Scheduler n8n
系統健康監控 每 5 分鐘
資料爬蟲 專業爬蟲邏輯
Google Drive 匯入 複雜資料處理 匯入監控
Telegram/LINE 通知 業績通知 系統告警
自動修復 本地 kubectl

已部署工作流程

2026-04-18 更新: 單一 UAT 環境監控 + 自動修復

系統監控類 (12 個)

# 工作流程 頻率 自動修復 說明
01 磁碟空間監控 每小時 自動清理 警告 80%、緊急 90%
02 SSL 證書監控 每日 09:00 30 天內到期告警
03 CI/CD Pipeline 通知 Webhook CI/CD 成功/失敗通知webhook 來源待定GitLab 已撤除)
04 資料庫備份監控 每日 10:00 檢查最新備份狀態
05 爬蟲執行監控 每 2 小時 重啟 scheduler 檢查爬蟲排程執行
06 K8s Pod 狀態監控 每 10 分鐘 自動重啟 Pod 應用健康檢查
07 Docker Registry 健康檢查 每 30 分鐘 Registry 可用性
11 Registry 健康監控 每 10 分鐘 詳細 Registry 狀態
12 Google Drive 匯入監控 每 30 分鐘 自動匯入狀態追蹤
15 Ollama/WebUI 健康監控 每 5 分鐘 自動重啟 AI 服務監控
16 K8s MOMO App 健康監控 每 5 分鐘 自動重啟 主應用深度監控
18 Clawdbot 健康監控 每 5 分鐘 自動修復 Bot 服務監控

環境監控類

# 工作流程 頻率 自動修復 說明
17 UAT 健康監控 每 5 分鐘 服務可用性檢查
18 PostgreSQL 資料庫監控 每 15 分鐘 資料庫狀態
20 UAT 自動修復機制 每 5 分鐘 自動重啟 服務自我修復

定期報告類 (3 個)

# 工作流程 頻率 說明
08 每日系統狀態報告 每日 09:00 應用、備份、爬蟲狀態彙報
09 每週業績摘要 每週一 09:00 週業績、訂單數、成長率
10 月初作業提醒 每月 1 日 09:00 月結待辦事項提醒

其他工作流程

# 工作流程 說明
13 PostgreSQL 慢查詢監控 慢查詢告警 + 自動 VACUUM
14 Windows 遠端控制 Telegram Bot 遠端控制
19 UAT 頁面健康監控 關鍵頁面可用性檢查
- EwoooC 系統健康監控 整體系統狀態

工作流程檔案位置

n8n-workflows/
├── 01-disk-space-monitor.json      # 磁碟空間監控
├── 02-ssl-certificate-monitor.json # SSL 證書監控
├── 03-cicd-pipeline-notify.json    # CI/CD 通知 (Webhook)
├── 04-backup-monitor.json          # 備份監控
├── 05-crawler-monitor.json         # 爬蟲監控
├── 06-k8s-pod-monitor.json         # K8s Pod 監控
├── 07-registry-health.json         # Registry 健康檢查
├── 08-daily-system-report.json     # 每日系統報告
├── 09-weekly-sales-summary.json    # 每週業績摘要
├── 10-monthly-reminder.json        # 月初提醒
├── 11-harbor-health-monitor.json   # Harbor 健康監控
├── 12-google-drive-import-monitor.json # Google Drive 匯入監控
├── 13-slow-query-monitor.json      # PostgreSQL 慢查詢監控
├── 14-ollama-health-monitor.json   # Ollama 健康監控
├── 17-uat-health-monitor.json      # UAT 健康監控
├── 18-postgres-health-monitor.json # PostgreSQL 資料庫監控
└── 20-auto-repair-uat.json         # UAT 自動修復機制

系統管理 API (供 n8n 呼叫)

端點 方法 說明
/api/system/cleanup POST 自動清理 (Docker prune, 日誌輪替)
/api/system/k8s/restart POST 重啟 K8s Deployment
/api/system/crawler/status GET 爬蟲執行狀態
/api/system/backup/status GET 備份狀態檢查
/api/system/ssl/check GET SSL 證書檢查
/api/system/registry/health GET Registry 健康檢查

通知模板管理系統

功能說明

提供 Web UI 管理 Telegram/LINE 通知訊息內容,可自訂 emoji、標題、內容格式。

管理頁面

  • URL: /notification_templates
  • 功能: 編輯模板、預覽訊息、初始化預設模板

API 端點

端點 方法 說明
/api/notification/templates GET 取得所有模板
/api/notification/templates/<code> GET 取得單一模板
/api/notification/templates/<code> PUT 更新模板
/api/notification/render POST 渲染模板 (n8n 呼叫)

預設模板列表 (14 個)

分類 模板代碼 說明
system disk_warning 磁碟空間警告 (80%)
system disk_critical 磁碟空間嚴重不足 (90%)
system cleanup_complete 自動清理完成
system ssl_warning SSL 證書即將到期
system pod_unhealthy K8s Pod 異常
system pod_restart_result Pod 重啟結果
system crawler_warning 爬蟲執行警告
system registry_unhealthy Registry 異常
system backup_warning 備份監控警告
system cicd_success CI/CD 成功
system cicd_failed CI/CD 失敗
report daily_report 每日系統狀態報告
business weekly_sales 每週業績摘要
business monthly_reminder 月初作業提醒

n8n 整合方式

在 n8n 中呼叫 /api/notification/render 取得格式化訊息後發送:

POST /api/notification/render
{
  "code": "disk_warning",
  "variables": {
    "usage_percent": 85,
    "free_gb": 15,
    "total_gb": 100
  }
}

n8n 管理指令

# SSH 到 UAT
ssh wooo@192.168.0.110

# 查看 n8n 容器狀態
docker ps | grep n8n

# 查看 n8n 日誌
docker logs momo-n8n --tail 50

# 列出所有工作流程
docker exec momo-n8n n8n list:workflow

# 手動觸發工作流程
docker exec momo-n8n n8n execute --id=H7O3cl6sUPSLM7UD

n8n API 存取

# 列出工作流程
curl -H "X-N8N-API-KEY: wooo_n8n_api_2026" \
  http://192.168.0.110:5678/api/v1/workflows

# 執行工作流程
curl -X POST -H "X-N8N-API-KEY: wooo_n8n_api_2026" \
  http://192.168.0.110:5678/api/v1/workflows/H7O3cl6sUPSLM7UD/activate

Docker Registry 詳細資訊

項目
外部 URL https://registry.wooo.work (HTTPS, 推薦)
內部 URL http://127.0.0.1:5000 (僅本機可存取)
帳號 admin
密碼 Wooo_Registry_2026
映像位置 registry.wooo.work/wooo/momo-pro-system:latest

⚠️ 安全提醒: Port 5000 已改為僅綁定 127.0.0.1,外部訪問必須透過 HTTPS 域名。

Rancher (K8s 管理平台)

項目
URL https://192.168.0.110:8443
帳號 admin
密碼 0B5-z2m0yxle6HtTq5WA
功能 K3s 集群管理、監控、日誌
K3s 集群 momo-k3s (已匯入)
Cluster ID c-52mz8
K8s 版本 v1.34.3+k3s1

Registry 映像管理

# 登入 Registry (使用 HTTPS 域名)
echo 'Wooo_Registry_2026' | docker login registry.wooo.work -u admin --password-stdin

# 映像位置 (使用域名)
registry.wooo.work/wooo/momo-pro-system:latest

CI/CD 流程GitLab 已撤除,待定新方案)

2026-04-18 更新: GitLab CE + GitLab CI/CD 已從基礎設施移除,新的 CI/CD 方案尚未定案。 目前部署以「本地 build + SCP + kubectl rollout restart」為暫時流程相關腳本待 CI/CD 選型後重寫。

手動觸發 K8s 更新

# SSH 到 UAT
ssh wooo@192.168.0.110

# 重啟 K8s Deployment會自動拉取最新 Image
kubectl rollout restart deployment/momo-app deployment/momo-scheduler -n momo

# 查看更新狀態
kubectl rollout status deployment/momo-app -n momo

Docker 容器DevOps 服務)

容器名稱 說明 Port
registry Docker Registry 容器 5000
watchtower Docker 映像自動更新 -
n8n Webhook 自動化 5678

K8s Pod應用服務

Pod 說明 資源限制
momo-app Flask 主應用 512Mi-4Gi / 200m-2000m
momo-postgres PostgreSQL 資料庫 256Mi-1Gi / 100m-500m
momo-scheduler 爬蟲排程服務 256Mi-2Gi / 100m-1000m

K8s 配置檔案

檔案 說明
k8s/02-configmap.yaml 環境變數配置Ollama AI、密碼策略等
k8s/04-momo-app.yaml Flask 主應用 Deployment + Google Drive 認證
k8s/05-scheduler.yaml 爬蟲排程 Deployment + Google Drive 認證
k8s/08-google-drive-secret.yaml Google OAuth 認證 Secret
k8s/nginx/monitor.conf VM Nginx 配置(含 Rancher 代理)

Nginx 代理路徑monitor.wooo.work

路徑 後端服務 Port
/grafana/ Docker Grafana 3000
/prometheus/ Prometheus 9090
/alertmanager/ Alertmanager 9093
/portainer/ Portainer 9000
/n8n/ n8n 5678
/pgadmin/ pgAdmin 8088
/loki/ Loki 3100
/rancher/ Rancher 8443 (HTTPS)
/k8s-grafana/ K8s Grafana 30030

關鍵路徑

用途 路徑
主資料庫 data/momo_database.db
UAT 資料庫 data/momo_database_uat.db
Google Drive 認證 config/google_credentials.json
排程器程式 run_scheduler.py
排程統計 data/scheduler_stats.json
系統日誌 logs/system.log

Ollama AI 服務

項目
Host http://192.168.0.188:11434
預設模型 llama3:70b-instruct-q2_K
API Key 0df8b4f247a4497998248f013ce92a17.vqSWDEK0RppTZIwcdT-ei-Sz
超時設定 基本 180 秒 / 文案生成 240 秒

K8s ConfigMap 設定

# k8s/02-configmap.yaml
OLLAMA_HOST: "http://192.168.0.188:11434"
OLLAMA_MODEL: "llama3:70b-instruct-q2_K"

環境變數

OLLAMA_HOST=http://192.168.0.188:11434
OLLAMA_MODEL=llama3:70b-instruct-q2_K
OLLAMA_API_KEY=0df8b4f247a4497998248f013ce92a17.vqSWDEK0RppTZIwcdT-ei-Sz

Ollama 伺服器健康監控 (2026-01-28 新增)

監控腳本: /home/ollama/scripts/ollama_health_monitor.sh 排程: 每 5 分鐘執行 (cron) n8n 工作流程: 14-ollama-health-monitor.json

監控項目:

項目 端點 說明
Nginx 進程檢查 確保代理服務正常
Ollama API http://127.0.0.1:11434/api/tags AI 模型服務
Open WebUI http://192.168.0.188/ Web 介面

自動修復機制:

問題 修復動作
Nginx 停止 sudo systemctl restart nginx
Ollama 停止 systemctl restart ollama
Open WebUI 502 (Docker 網路失效) sudo systemctl restart docker
Open WebUI 容器卡住 docker restart open-webui

SSH 連線:

ssh ollama@192.168.0.188
# 密碼: 0936223270

手動檢查:

# 執行健康檢查
/home/ollama/scripts/ollama_health_monitor.sh

# 查看日誌
tail -f /var/log/ollama_health_monitor.log

Ollama 伺服器安全加固 (2026-02-02 新增)

安全腳本: scripts/security/harden_ollama_server.sh

已安裝防護:

服務 配置 說明
Fail2Ban SSH 3 次失敗封鎖 1 小時 防暴力破解
UFW 防火牆 預設拒絕入站 網路存取控制

UFW 規則:

# 公開服務
22/tcp    # SSH
80/tcp    # HTTP
443/tcp   # HTTPS

# 僅限內網 (192.168.0.0/24)
11434     # Ollama API
3000      # Open WebUI
5678      # n8n
8080      # SearXNG

管理指令:

# 查看 Fail2Ban 封鎖狀態
sudo fail2ban-client status sshd

# 查看防火牆規則
sudo ufw status verbose

Kali Linux DevSecOps 工作站

項目
IP 192.168.0.112
用戶 kali
用途 集中式安全掃描、滲透測試、弱點管理

SSH 連線

ssh kali@192.168.0.112

目錄結構

/home/kali/
├── projects/                    # 專案程式碼 (Git clone)
│   └── momo-pro-system/         # 主專案
└── scripts/                     # 自動化掃描腳本
    ├── port_monitor.py          # 端口監控
    ├── port_baseline.json       # 端口基線
    ├── code_security_scan.py    # 程式碼安全掃描 (Bandit)
    ├── registry_image_scan.py   # 容器映像掃描 (Trivy)
    └── logs/                    # 掃描日誌

自動化掃描工具

1. 端口監控 (port_monitor.py)

  • 執行頻率: 每小時
  • 監控目標: 192.168.0.110, 192.168.0.188
  • 功能: Nmap 掃描,與基線比對,發現新端口時發送 Telegram 告警
  • Cron: 0 * * * * /usr/bin/python3 /home/kali/scripts/port_monitor.py

2. 程式碼安全掃描 (code_security_scan.py)

  • 執行頻率: 每日 08:00
  • 工具: Bandit (Python 安全分析器)
  • 功能: 掃描 ~/projects 下所有專案,發送 Telegram 報告
  • Cron: 0 8 * * * /usr/bin/python3 /home/kali/scripts/code_security_scan.py

3. Registry 映像掃描 (registry_image_scan.py)

  • 執行頻率: 每週日 09:00
  • 工具: Trivy (容器弱點掃描器)
  • 功能: 掃描 Docker Registry 中的映像,發送 Telegram 報告
  • Cron: 0 9 * * 0 /usr/bin/python3 /home/kali/scripts/registry_image_scan.py
  • 掃描目標: registry.wooo.work/wooo/momo-pro-system:latest

基線端口清單 (2026-01-25 更新)

192.168.0.110 (外部可見):

Port Service
22 SSH
80 HTTP
443 HTTPS (SSL, Registry/mo.wooo.work)

⚠️ Port 5050, 5678, 9100 已隱藏,僅本地可存取

192.168.0.188 (外部可見):

Port Service
22 SSH
80 HTTP
443 HTTPS

手動執行掃描

# 端口掃描
python3 ~/scripts/port_monitor.py

# 程式碼安全掃描 (Bandit)
python3 ~/scripts/code_security_scan.py

# Registry 映像掃描 (Trivy)
python3 ~/scripts/registry_image_scan.py

WireGuard VPN (WG-Easy)

項目
管理介面 http://192.168.0.112:51821
外部端點 114.32.151.246:51820/udp
密碼 Wooo_VPN_2026
允許網段 192.168.0.0/24, 10.0.0.0/8
DNS 8.8.8.8, 8.8.4.4

使用方式:

  1. 開啟管理介面 http://192.168.0.112:51821
  2. 輸入密碼登入
  3. 點擊「+ New」建立新用戶
  4. 手機下載 WireGuard App掃描 QR Code 即可連線

Docker 容器管理:

# 查看狀態
docker ps --filter name=wg-easy

# 重啟服務
docker restart wg-easy

# 查看日誌
docker logs wg-easy

⚠️ 安全提醒: 需要在路由器設定 Port Forwarding: 51820/UDP → 192.168.0.112:51820


🛡️ 服務變更安全協議 (2026-02-08 新增)

核心原則: 避免「改一個壞一個」,每次變更前必須確認所有相關服務狀態

服務依賴關係圖

┌─────────────────────────────────────────────────────────────────────────────┐
│                          UAT 服務依賴架構圖                                   │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  ┌─────────────────┐                                                        │
│  │   VM Nginx      │ ← 所有外部流量入口                                      │
│  │  (Port 80/443)  │                                                        │
│  └────────┬────────┘                                                        │
│           │                                                                 │
│  ┌────────┴────────────────────────────────────────────────────────┐       │
│  │                                                                  │       │
│  ▼                    ▼                    ▼                                │       │
│ ┌──────────┐    ┌──────────┐    ┌──────────┐                                │       │
│ │mo.wooo   │    │monitor.  │    │registry. │                                │       │
│ │.work     │    │wooo.work │    │wooo.work │                                │       │
│ └────┬─────┘    └────┬─────┘    └────┬─────┘                                │       │
│      │               │               │                                       │       │
│      ▼               ▼               ▼                                       │       │
│ ┌──────────┐    ┌──────────┐    ┌──────────┐                                │       │
│ │K8s       │    │Superset  │    │Registry  │                                │       │
│ │momo-app  │    │Grafana   │    │Docker    │                                │       │
│ │          │    │Prometheus│    │          │                                │       │
│ └────┬─────┘    │n8n       │    └──────────┘                                │       │
│      │          │Portainer │                                                 │       │
│      │          └──────────┘                                                 │       │
│      ▼                                                                       │       │
│ ┌──────────┐                                                                 │       │
│ │momo-     │                                                                 │       │
│ │postgres  │                                                                 │       │
│ └──────────┘                                                                 │       │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

⚠️ 重要依賴關係:
1. Nginx 故障 → 所有外部服務不可訪問
2. Docker 故障 → Superset、n8n、Registry 全停
3. K8s 故障 → momo-app、momo-scheduler、momo-postgres 全停
4. Registry 故障 → K8s 無法拉取新映像

變更前必做檢查清單

在進行任何配置變更之前,必須執行以下檢查:

# 1. 記錄當前所有服務狀態(變更前快照)
ssh wooo@192.168.0.110 "
echo '=== 變更前服務狀態快照 ==='
echo '時間:' \$(date '+%Y-%m-%d %H:%M:%S')
echo ''
echo '--- Docker 容器 ---'
docker ps --format 'table {{.Names}}\t{{.Status}}' | head -20
echo ''
echo '--- K8s Pods ---'
kubectl get pods -n momo --no-headers 2>/dev/null
echo ''
echo '--- 健康檢查 ---'
curl -s -o /dev/null -w 'mo.wooo.work: %{http_code}\n' https://mo.wooo.work/health
curl -s -o /dev/null -w 'Superset: %{http_code}\n' https://monitor.wooo.work/superset/login/
curl -s -o /dev/null -w 'n8n: %{http_code}\n' http://127.0.0.1:5678/ 2>/dev/null || echo 'n8n: 連線失敗'
" | tee /tmp/pre_change_status.txt

服務恢復 SOP

1. Docker 容器停止 (Exit 128/137)

常見原因: 系統重啟、Docker 重啟、OOM

# 檢查停止的容器
ssh wooo@192.168.0.110 "docker ps -a --filter status=exited"

# 恢復 n8n (如有衝突需先刪除)
ssh wooo@192.168.0.110 "docker rm -f momo-n8n; cd /home/wooo && docker compose up -d n8n"

# 恢復 Superset
ssh wooo@192.168.0.110 "cd /home/wooo/momo_pro_system/docker/superset && docker compose down && docker compose up -d"

# 恢復 Registry
ssh wooo@192.168.0.110 "cd /home/wooo/devops/registry && docker compose up -d"

2. Nginx 502 Bad Gateway

診斷流程:

# Step 1: 確認後端容器狀態
docker ps | grep <service_name>

# Step 2: 測試容器內部
docker exec <container> curl -s http://127.0.0.1:<port>/health

# Step 3: 如果內部正常但外部 502 = Docker 網路問題
sudo systemctl restart docker

3. Superset 路徑問題 (/superset/superset/)

根本原因: Superset 內部路由已是 /superset/...Nginx proxy_redirect / /superset/ 會重複添加

正確的 Nginx 配置:

location /superset/ {
    proxy_pass http://127.0.0.1:8088/;

    # 關鍵Superset 內部已是 /superset/,不需要再添加
    proxy_redirect /superset/ /superset/;
    proxy_redirect ~^/(?!superset)(.*)$ /superset/$1;

    # 只重寫 static 和 api 路徑
    sub_filter '"/static/' '"/superset/static/';
    sub_filter "'/static/" "'/superset/static/";
    sub_filter_once off;
}

Superset 配置 (superset_config.py):

ENABLE_PROXY_FIX = True
PROXY_FIX_CONFIG = {
    "x_for": 1,
    "x_proto": 1,
    "x_host": 1,
    "x_prefix": 0,  # 必須為 0Nginx 已處理前綴
}

4. K8s Pod 問題

# 查看 Pod 狀態
kubectl get pods -n momo

# 查看 Pod 詳情
kubectl describe pod <pod-name> -n momo

# 重啟 Deployment
kubectl rollout restart deployment/momo-app deployment/momo-scheduler -n momo

# 查看日誌
kubectl logs -f deployment/momo-app -n momo --tail=100

變更後驗證清單

每次變更完成後,必須執行以下驗證:

# 完整服務健康檢查
ssh wooo@192.168.0.110 "
echo '=== 變更後服務驗證 ==='
echo '時間:' \$(date '+%Y-%m-%d %H:%M:%S')
echo ''

# Docker 容器
echo '--- Docker 容器狀態 ---'
docker ps --format 'table {{.Names}}\t{{.Status}}' | head -15

# K8s
echo ''
echo '--- K8s Pods ---'
kubectl get pods -n momo --no-headers 2>/dev/null

# 健康檢查
echo ''
echo '--- 健康檢查 ---'
curl -s -o /dev/null -w 'mo.wooo.work: %{http_code}\n' https://mo.wooo.work/health
curl -s -o /dev/null -w 'Superset 登入: %{http_code}\n' https://monitor.wooo.work/superset/login/
curl -s -o /dev/null -w 'n8n: %{http_code}\n' http://127.0.0.1:5678/ 2>/dev/null || echo 'n8n: 連線失敗'
curl -s -o /dev/null -w 'Registry: %{http_code}\n' https://registry.wooo.work/v2/ 2>/dev/null || echo 'Registry: 連線失敗'
curl -s -o /dev/null -w 'CI/CD Dashboard: %{http_code}\n' https://mo.wooo.work/cicd 2>/dev/null

echo ''
echo '=== 驗證完成 ==='
"

Claude 協作改進方案

2026-02-08 新增 - 回應用戶「改一個壞一個」的反饋

1. 變更前自動快照

  • 在進行任何配置變更前Claude 應主動執行「變更前必做檢查清單」
  • 將結果保存以便變更後對比

2. 相關服務連帶檢查

  • 修改 Nginx → 同時檢查所有代理的服務
  • 修改 Docker Compose → 同時檢查相關容器
  • 修改 K8s YAML → 同時檢查 Pod 狀態

3. 變更後完整驗證

  • 不只驗證目標服務,還要驗證所有可能受影響的服務
  • 使用「變更後驗證清單」確保沒有遺漏

4. 文檔記錄

  • 每次修復重要問題後,立即更新 CLAUDE.md
  • 記錄問題症狀、根本原因、解決方案

常見問題與解法

1. Scheduler 無法匯入 Google Drive 檔案

症狀: 日誌顯示 找不到認證檔案: config/google_credentials.json

K8s 解法: 使用 initContainer 從 Secret 複製認證到可寫入目錄

# k8s/04-momo-app.yaml & k8s/05-scheduler.yaml
initContainers:
  - name: copy-google-credentials
    image: busybox:1.36
    command: ['sh', '-c', 'cp /secrets/* /config/ && chmod 644 /config/*']
    volumeMounts:
      - name: google-drive-secrets
        mountPath: /secrets
        readOnly: true
      - name: momo-config-volume
        mountPath: /config
volumes:
  - name: google-drive-secrets
    secret:
      secretName: google-drive-credentials
  - name: momo-config-volume
    emptyDir: {}

Docker 解法: 確認 docker-compose.yml 中 scheduler 有掛載 config 目錄

scheduler:
  volumes:
    - ./config:/app/config:ro  # 必須有這行

2. 資料沒有同步到 realtime_sales_monthly

症狀: daily_sales_snapshot 有資料但 realtime_sales_monthly 沒有

解法: 檢查 services/import_service.py 中的同步邏輯 (約 line 404-459)

3. LINE 通知發送失敗

症狀: You have reached your monthly limit

原因: LINE Notify 免費方案每月 1000 則限制,需等待下月重置

4. 502 Bad Gateway (Docker 網路問題)

2026-01-28 新增 - 詳細排查過程與自動修復方案

症狀:

  • 訪問 https://mo.wooo.work/ 返回 502 Bad Gateway
  • Nginx 無法連接到後端服務

診斷步驟:

  1. 檢查 Docker 容器狀態

    ssh wooo@192.168.0.110 "sudo docker ps | grep momo"
    

    結果:容器顯示 Up About a minute (healthy),看起來正常

  2. 檢查外部端口連通性

    curl -v http://127.0.0.1:5001/health
    

    結果:Connection reset by peer 或超時(約 30 秒)

  3. 檢查容器內部健康

    docker exec momo-pro-system curl -s http://127.0.0.1:80/health
    

    結果:{"status": "healthy"} - 容器內部正常!

  4. 診斷結論

    • 容器內部服務正常運行
    • Docker 端口映射/網路轉發失效
    • Docker-proxy 進程存在但不轉發流量

根本原因: Docker 網路棧故障,通常發生在:

  • 系統重啟後 Docker 網路未正確初始化
  • iptables 規則被其他服務清除
  • Docker daemon 內部狀態不一致

解決方案:

# 重啟 Docker 服務(會重建網路棧)
sudo systemctl restart docker

# 等待容器自動啟動(約 30 秒)
sleep 30

# 驗證服務恢復
curl -s https://mo.wooo.work/health

自動修復腳本: 見 scripts/docker_health_monitor.sh


🔧 自動化監控與修復

Docker 網路健康監控 (Cron)

腳本位置: /home/wooo/scripts/docker_health_monitor.sh

功能:

  1. 每 5 分鐘檢查 mo.wooo.work 健康狀態
  2. 檢測到 502/超時時自動執行診斷
  3. 確認是 Docker 網路問題後自動重啟 Docker
  4. 發送 Telegram 通知

Cron 設定:

# 每 5 分鐘執行健康檢查
*/5 * * * * /home/wooo/scripts/docker_health_monitor.sh >> /var/log/docker_health_monitor.log 2>&1

監控邏輯:

外部健康檢查 (curl mo.wooo.work)
        │
        ├── 成功 (HTTP 200) → 結束
        │
        └── 失敗 (502/超時)
                │
                ├── 檢查容器內部 (docker exec curl)
                │       │
                │       ├── 內部正常 → Docker 網路問題 → 重啟 Docker
                │       │
                │       └── 內部失敗 → 應用問題 → 重啟容器
                │
                └── 發送 Telegram 告警

Telegram 告警範例:

🔴 MOMO Pro 服務異常

症狀: 502 Bad Gateway
診斷: Docker 網路轉發失效
動作: 已自動重啟 Docker 服務
時間: 2026-01-28 15:30:00

5. K8s ImagePullBackOff (Registry 服務中斷)

2026-01-28 新增 - Docker Registry 服務中斷導致 K8s 無法拉取映像檔

症狀:

  • K8s Pods 顯示 ImagePullBackOffErrImagePull
  • Google Drive 自動匯入停止運作
  • Scheduler 和 App 服務中斷

診斷步驟:

  1. 檢查 K8s Pod 狀態

    sudo kubectl get pods -n momo
    

    結果:momo-appmomo-scheduler 顯示 ImagePullBackOff

  2. 查看詳細錯誤

    sudo kubectl describe pod <pod-name> -n momo
    

    結果:Failed to pull image: dial tcp 192.168.0.110:5000: connect: connection refused

  3. 檢查 Registry 服務

    docker ps | grep registry
    

    結果Registry 容器未運行

根本原因:

  • Docker Registry 服務停止(可能因系統重啟)
  • Registry 端口配置改為 127.0.0.1:5000安全配置導致 K8s 無法連線

解決方案:

# 1. 啟動 Registry
cd /home/wooo/devops/registry
docker compose up -d

# 2. 更新 K8s 使用 HTTPS 域名
# 修改 k8s/04-momo-app.yaml 和 k8s/05-scheduler.yaml
# 將 image: 192.168.0.110:5000/wooo/momo-pro-system:latest
# 改為 image: registry.wooo.work/wooo/momo-pro-system:latest

# 3. 更新 registry secret
kubectl delete secret registry-secret -n momo
kubectl create secret docker-registry registry-secret \
  --docker-server=registry.wooo.work \
  --docker-username=admin \
  --docker-password=Wooo_Registry_2026 \
  -n momo

# 4. 套用配置並重啟
kubectl apply -f k8s/04-momo-app.yaml -f k8s/05-scheduler.yaml
kubectl rollout restart deployment/momo-app deployment/momo-scheduler -n momo

自動修復腳本: 見 scripts/registry_health_monitor.sh

6. Scheduler CrashLoopBackOff (run_scheduler.py 遺失)

2026-02-02 新增 - Scheduler Pod 重啟 387 次

症狀:

  • momo-scheduler Pod 顯示 CrashLoopBackOff
  • 日誌:python: can't open file '/app/run_scheduler.py': [Errno 2] No such file or directory

原因: run_scheduler.py 檔案在某次部署中遺失

解決方案:

# 1. 確認檔案存在
ls /Users/ogt/momo-pro-system/run_scheduler.py

# 2. 重建 Docker 映像
cd /home/wooo/momo_pro_system
docker build -t registry.wooo.work/wooo/momo-pro-system:latest .
docker push registry.wooo.work/wooo/momo-pro-system:latest

# 3. 重啟 scheduler
kubectl rollout restart deployment/momo-scheduler -n momo

7. vendor-stockout 500 錯誤 (模板路徑錯誤)

2026-02-02 新增 - 模板檔案位置不正確

症狀:

  • 訪問 /vendor-stockout/ 返回 Internal Server Error
  • 日誌:jinja2.exceptions.TemplateNotFound: vendor_stockout/index.html

原因: 模板檔案放在根目錄 (vendor_stockout_index.html),而非正確路徑 (templates/vendor_stockout/index.html)

解決方案:

# 建立正確目錄並移動模板
mkdir -p templates/vendor_stockout
mv vendor_stockout_*.html templates/vendor_stockout/

# 重新命名為正確名稱
mv templates/vendor_stockout/vendor_stockout_index.html templates/vendor_stockout/index.html
# ... 其他檔案同理

8. Alertmanager 無法發送 Telegram 告警

2026-02-02 新增 - 訊息模板語法錯誤

症狀:

  • Alertmanager 日誌持續報錯
  • 錯誤:template: :12:27: can't evaluate field StartsAt in type *template.Data

原因: Telegram 訊息模板中 .StartsAt 放在 {{ range .Alerts }} 區塊外,而 StartsAt 是每個 Alert 的屬性

解決方案:

# k8s/monitoring/values-prometheus.yaml

# ❌ 錯誤寫法
{{ range .Alerts }}
📝 摘要: {{ .Annotations.summary }}
{{ end }}
⏰ 時間: {{ .StartsAt.Local.Format "..." }}  # 在 range 外,.StartsAt 不存在

# ✅ 正確寫法
{{ range .Alerts }}
📝 摘要: {{ .Annotations.summary }}
⏰ 時間: {{ .StartsAt.Local.Format "..." }}  # 在 range 內
{{ end }}

套用修復:

# 更新 Helm values
scp k8s/monitoring/values-prometheus.yaml wooo@192.168.0.110:/home/wooo/momo_pro_system/k8s/monitoring/

# 升級 Prometheus stack
helm upgrade prometheus prometheus-community/kube-prometheus-stack \
  -n monitoring \
  -f /home/wooo/momo_pro_system/k8s/monitoring/values-prometheus.yaml

# 重啟 Alertmanager
kubectl rollout restart statefulset/alertmanager-prometheus-kube-prometheus-alertmanager -n monitoring

🔧 Registry 自動監控

Registry 健康監控 (Cron)

腳本位置: /home/wooo/scripts/registry_health_monitor.sh

功能:

  1. 每 5 分鐘檢查 Registry 服務狀態
  2. 檢測到 Registry 停止時自動啟動
  3. 發送 Telegram 告警通知

Cron 設定:

# 每 5 分鐘執行 Registry 健康檢查
*/5 * * * * /home/wooo/scripts/registry_health_monitor.sh >> /var/log/registry_health_monitor.log 2>&1

排程任務設定

任務 頻率 說明
Google Drive 自動匯入 每 30 分鐘 匯入 即時業績_當日.xlsx
商品看板爬蟲 每 1 小時 爬取 momo 商品資料
EDM 限時搶購爬蟲 每 1 小時 爬取 EDM 活動
購物節活動爬蟲 每 6 小時 爬取節慶活動

🔄 系統重開機自動啟動機制 (2026-01-31 新增)

概述

系統重開機後,透過 systemd 服務自動啟動所有必要服務,確保服務可用性。

服務啟動順序

重開機完成
    ↓ (30 秒延遲,等待系統穩定)
1. 確認 Docker 服務啟動
    ↓
2. 停止 Supabase 非必要服務 (減少資源競爭)
    ↓
3. 清理並啟動 Docker Registry (等待 healthy)
    ↓
4. 重啟 K8s momo-app/scheduler (等待就緒)
    ↓
5. 啟動監控服務
    ↓
6. 健康檢查 + Telegram 通知

⚠️ 2026-04-18 備註(ADR-008): 以下 systemd 服務設定與路徑為 110 主機早期架構,188 的 Docker Compose 自帶 restart: unless-stopped 即可自動恢復,目前 188 不需要此 systemd 腳本。保留本章以供 110 周邊服務(Harbor/Sentry 等)啟動順序參考。

相關檔案(110 周邊服務用,若仍存在)

檔案 位置 說明
啟動腳本 /home/wooo/momo_pro_system/scripts/tools/system_startup.sh ⚠️(110 上路徑已空置,腳本存在與否需確認) 舊啟動腳本
systemd 服務 /etc/systemd/system/momo-startup.service 開機自動執行
日誌檔案 /var/log/momo_startup.log 啟動日誌

188 主機啟動策略(實況)

188 不需要客製 systemd 服務 — Docker Compose 的 restart: unless-stopped 已足夠:

# docker-compose.yml(V12.0 已設定)
services:
  momo-app:
    restart: unless-stopped
  momo-scheduler:
    restart: unless-stopped
  momo-db:
    restart: unless-stopped

開機後 Docker daemon 啟動 → 容器自動恢復 → 無需額外腳本介入。

故障排除

問題 解決方法
Registry 啟動失敗 手動執行 cd /home/wooo/devops/registry && docker compose down && docker compose up -d
K8s Pod 卡在 Init 檢查 Registry 是否健康,重啟 Pod
服務未自動啟動 確認 systemctl is-enabled momo-startup.service 返回 enabled
查看詳細日誌 cat /var/log/momo_startup.logjournalctl -u momo-startup.service -n 100

模組化輔助腳本庫

deploy/lib/
├── registry.sh    # Registry 管理函數
├── k8s.sh         # K8s 管理函數
├── monitoring.sh  # 監控與 Telegram 通知
└── systemd.sh     # Systemd 服務管理

已完成功能 (2026-02)

  • SSL 憑證配置 (Let's Encrypt)
  • UAT 服務自動啟動腳本優化
  • 服務依賴關係文檔建立
  • Harbor 移除,改用 Docker Registry (registry.wooo.work)
  • CI/CD Dashboard 完整版 (/cicd 頁面)
  • 監控告警環境標籤

已完成功能 (2026-01)

  • 廠商缺貨郵件系統(含自訂模板編輯)
  • 缺貨清單分頁 UI待發送/已發送分開)
  • 郵件發送歷史頁面(含內容預覽)
  • 每日業績 Telegram/LINE 通知(含趨勢 emoji
  • 修復 scheduler config 目錄掛載問題
  • PostgreSQL 資料庫支援(雙資料庫架構)
  • 商品看板效能優化(索引 + FileLock 快取鎖)
  • K8s Google Drive 認證initContainer 架構)
  • Ollama AI 服務配置192.168.0.188
  • Rancher K8s 管理平台部署
  • K3s 集群匯入 Ranchermomo-k3s
  • CI/CD 安全掃描 (Bandit + Trivy) — 原 GitLab CI 已撤除,待新方案重建
  • Kali Linux DevSecOps 工作站192.168.0.112
  • 自動化端口監控與程式碼掃描 (Cron)
  • Registry HTTPS 安全配置(隱藏 5000 端口)
  • WireGuard VPN (WG-Easy) 遠端存取
  • 系統重開機自動啟動機制 (systemd + 健康檢查)

更新記錄 (2026-01-22 ~ 02-13)

⚠️ 2026-04-18 補正說明(ADR-008): 以下歷史紀錄多處提到「K8s 遷移」「kubectl rollout restart」「/home/wooo/momo_pro_system/ 路徑」等,經實地 SSH 審計確認 EwoooC 從未切換到 K3s/K8s,實際始終是 188 上的 Docker Compose。相關歷史段落保留為「文件考古」,不可據此執行任何部署動作。最新部署 SOP 見本文件開頭「🌐 環境架構總覽」與「部署指令」章節。

2026-02-13重開機服務修復與 Clawdbot 整合

1. 系統啟動腳本更新 (v2.0)

問題: 每次重開機後服務異常Harbor 已移除但腳本仍嘗試啟動

修復內容:

  • 更新 scripts/tools/system_startup.sh 為 v2.0 版本
  • 移除 Harbor 相關啟動邏輯
  • 改用 docker-registry 作為容器倉庫
  • 簡化啟動流程Docker → Registry → n8n → Superset → K8s

啟動腳本新流程:

1. 檢查 Docker 服務
2. 啟動 Docker Registry (docker-registry)
3. 啟動 n8n (momo-n8n)
4. 啟動 Superset (docker compose)
5. 重啟 K8s 應用 (momo-app, momo-scheduler)
6. 健康檢查 + Telegram 通知

2. Monitor 首頁更新

問題: monitor.wooo.work 顯示許多不存在的服務 (Grafana Docker, Portainer, Loki, Metabase 等)

修復:

  • 重新設計 Monitor 首頁,只顯示實際部署的服務
  • 移除不存在的服務連結Docker Grafana、Portainer、Loki、Metabase、Nextcloud、Grist、pgAdmin、cAdvisor

目前顯示的服務:

分類 服務
應用服務 EwoooC (mo.wooo.work / momo.wooo.work)
開發工具 Docker Registry、n8n
監控服務 Grafana (K8s)、Prometheus、Alertmanager
BI 分析 Apache Superset

3. Harbor 完全移除

  • 清理所有 Harbor 相關容器
  • 更新域名健康監控腳本移除 Harbor 檢查
  • 改用 docker-registry 容器

4. Clawdbot 整合腳本 (Ollama Server)

新增腳本 (位於 192.168.0.188:~/scripts/):

腳本 功能 使用方式
health_check.sh 服務健康檢查 /ssh ~/scripts/health_check.sh
k8s_manage.sh K8s 管理 /ssh ~/scripts/k8s_manage.sh [pods|logs|restart]
backup_manage.sh 備份管理 /ssh ~/scripts/backup_manage.sh [status|run]
sales_query.sh 業績查詢 /ssh ~/scripts/sales_query.sh [today|status]
gemini_cost_report.sh Gemini 費用 每日 9:00 Cron 自動發送

SSH Key 設定:

  • Ollama → UAT SSH Key 已添加到 authorized_keys
  • 允許 Clawdbot 透過 SSH 執行 K8s 管理命令

5. 域名監控更新

檔案: scripts/domain-health-monitor.sh

  • 移除 Metabase 監控(未部署)
  • 目前監控服務EwoooC App、Monitor、Registry、n8n、Superset

6. 監控告警異常修復 (2026-02-13 06:30)

發現的問題

  1. n8n 容器不存在 - 容器未設置自動重啟或被意外刪除
  2. Superset 容器未啟動 - 容器意外停止且未自動重啟
  3. 監控腳本配置錯誤 - n8n 和 Superset 監控路徑錯誤(寫成 K8s 但實際是 Docker

服務修復記錄

服務 問題 修復方式 修復時間
n8n 容器不存在 docker run -d --name momo-n8n ... 06:32
Superset 容器停止 cd docker/superset && docker compose up -d 06:33
Clawdbot Gateway 服務停止 systemctl --user start clawdbot-gateway 06:33

監控腳本重大更新 (scripts/domain-health-monitor.sh)

# 舊配置(錯誤)
- ["https://monitor.wooo.work/n8n/healthz"]="200|n8n (K8s)|kubectl rollout restart ..."
- ["https://monitor.wooo.work/superset/health"]="200|Superset (K8s)|kubectl rollout restart ..."
- 固定等待時間 30 秒

# 新配置(正確)
+ ["http://127.0.0.1:5678/"]="200|n8n|docker start momo-n8n ..."|30"
+ ["http://127.0.0.1:8088/health"]="200|Superset|cd docker/superset && docker compose up -d|60"
+ 加入重試機制(最多 3 次,每次間隔 10 秒)

服務優先級定義

優先級 服務 說明
1 (最高) EwoooC App 核心業務
2 Registry 映像倉庫
3 n8n 自動化工作流程
4 Superset BI 分析平台
5 Monitor 頁面 監控入口

最終服務狀態 (06:38 驗證)

服務 狀態碼 狀態
EwoooC App (mo) 200 正常
EwoooC App (momo) 200 正常
Registry 401 正常 (需認證)
n8n 200 正常
Superset 200 正常
Monitor 200 正常

變更檔案

  • scripts/domain-health-monitor.sh - 修正監控路徑、增加等待時間、加入重試機制

7. 下午修復 (2026-02-13 17:00)

Clawdbot Gateway 穩定性優化

  • 問題Clawdbot Gateway 經常異常,出現鎖定檔案衝突
  • 原因:舊進程未正確終止,留下 ~/.clawdbot/gateway.lock
  • 修復:在 systemd service 添加 ExecStartPre 清理鎖定檔案
  • 位置~/.config/systemd/user/clawdbot-gateway.service (192.168.0.188)
[Service]
ExecStartPre=/bin/bash -c 'pkill -9 clawdbot 2>/dev/null || true; rm -f ~/.clawdbot/gateway.lock 2>/dev/null || true; sleep 2'
ExecStart=/usr/bin/clawdbot gateway
Restart=always
RestartSec=15

已修復問題

問題 狀態 修復方式
Monitor Logo 破圖 已修復 創建 /var/www/monitor/monitor-static/images/ 並複製 logo
Superset 404 已修復 Nginx 添加 /superset/ 重定向和 /superset/login/ 代理規則
Clawdbot Linger 已修復 loginctl enable-linger ollama 已啟用

Superset Nginx 配置修復

# 根路徑重定向
location /superset/ {
    if ($request_uri = /superset/) {
        return 302 /superset/welcome/;
    }
    # ... 其他配置
}

# 登入頁面代理到正確路徑
location = /superset/login/ {
    proxy_pass http://superset_backend/login/;
    # ... 其他 headers
}

待修復問題

問題 狀態 說明
Clawdbot Telegram 衝突 待修復 Bot Token 與監控告警系統共用,需創建新的 Telegram Bot 給 Clawdbot

最終服務狀態 (17:09 驗證)

服務 狀態碼 狀態
Monitor Logo 200 正常
Superset 根路徑 302 重定向正常
Superset Login 200 正常
MOMO App 200 正常

8. 晚間修復 (2026-02-13 19:30-20:00)

Superset 登入轉圈問題修復

  • 問題Superset 登入頁面一直轉圈,無法登入
  • 原因/static/ 靜態資源路徑返回 302 重定向而非正確的代理
  • 修復:修改 Nginx /static/ location 為直接代理到 Superset backend
# 修正後
location ^~ /static/ {
    proxy_pass http://superset_backend/static/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
}

n8n 工作流程重新匯入

  • 問題n8n 只有 1 個工作流程(應有 29 個)
  • 原因n8n 容器重建後資料遺失
  • 修復:從 n8n-workflows/ 目錄重新匯入所有 27+ 個工作流程

Alertmanager 路由規則更新

  • 問題Telegram 告警未正確發送到 momo namespace 的告警
  • 修復Helm upgrade prometheus-stack 套用正確的路由規則

n8n executeCommand 節點問題

  • 問題n8n 2.6.4 版本不支援 executeCommand 節點類型
  • 影響工作流程UAT 自動修復、Clawdbot 健康監控、UAT 頁面健康監控
  • 修復:停用有問題的工作流程,改用 Cron 腳本自動修復(已正常運作)

自動修復機制確認

機制 狀態 說明
Cron domain-health-monitor.sh 運作中 每 5 分鐘檢查 7 個服務,自動修復
n8n 磁碟空間監控 運作中 自動清理磁碟
n8n 健康監控 運作中 HTTP 檢查 UAT 服務
Prometheus Alertmanager 運作中 K8s momo namespace 告警 → Telegram
n8n 自動修復工作流程 已停用 executeCommand 不支援,改用 Cron

最終驗證 (20:00)

  • Superset 登入成功
  • 所有 7 個監控服務正常
  • Telegram 告警測試成功
  • Cron 自動修復機制運作正常
  • 29 個 n8n 工作流程已載入

9. 進階自動修復系統部署 (2026-02-13 20:15)

新增自動修復腳本 (scripts/auto-repair/):

腳本 功能 執行頻率
oom-handler.sh OOM 檢測,自動增加記憶體 +50% 並重啟 每 15 分鐘
postgres-repair.sh 連線檢測、死鎖處理、VACUUM、週備份 每 30 分鐘
auto-rollback.sh 連續 5 次健康檢查失敗,自動回滾版本 每 5 分鐘
master-auto-repair.sh 主協調腳本 每 5 分鐘

Cron 設定:

*/5 * * * * /home/wooo/scripts/auto-repair/master-auto-repair.sh >> /var/log/master_auto_repair.log 2>&1

自動修復能力總覽:

問題類型 自動修復方式 狀態
OOM 記憶體不足 自動增加限制 +50%,重啟 Pod 已實作
PostgreSQL 連線失敗 自動重啟 Pod 已實作
PostgreSQL 死鎖 終止長時間查詢 已實作
表膨脹/Dead Tuples 自動 VACUUM ANALYZE 已實作
程式碼 Bug (5次失敗) 自動回滾到上一版本 已實作
服務無回應 Cron 腳本自動重啟 已實作

新增 Prometheus 告警規則 (k8s/monitoring/complete-alerting-rules.yaml):

完整的 Prometheus → Alertmanager → Telegram → 自動修復 流程配置:

# 告警規則群組
- name: memory-alerts         # OOM 相關告警
- name: postgres-alerts       # PostgreSQL 告警
- name: app-health-alerts     # 應用健康告警
- name: infrastructure-alerts # 基礎設施告警
告警名稱 觸發條件 告警等級 自動修復標籤
PodOOMKilled OOMKilled 事件 critical oom-handler
HighMemoryUsage 記憶體 > 85% warning
MemoryNearLimit 記憶體 > 95% critical oom-handler
PostgresDown pg_up == 0 critical postgres-repair
PostgresHighConnections 連線 > 80% warning postgres-repair
PostgresDeadlocks 死鎖發生 warning postgres-repair
PostgresSlowQueries 查詢 > 5 分鐘 warning postgres-repair
MomoAppDown 健康檢查失敗 critical auto-rollback
HighHTTP5xxRate 5xx > 5% warning auto-rollback
PodRestartTooMany 1小時重啟>5次 warning auto-rollback
DiskSpaceLow 磁碟 < 15% warning disk-cleanup
DiskSpaceCritical 磁碟 < 5% critical disk-cleanup
MomoSchedulerDown Scheduler 停止 critical domain-health-monitor

監控 → 告警 → 自動修復 完整流程圖:

┌─────────────────────────────────────────────────────────────────────────┐
│                    完整監控與自動修復架構                                │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  監控層                告警層                    修復層                  │
│  ───────              ───────                  ───────                  │
│                                                                         │
│  ┌─────────┐         ┌─────────┐              ┌─────────────────┐       │
│  │Prometheus│ ──────▶│Alertmgr │ ──Telegram──▶│ Cron 自動修復    │       │
│  │ 指標收集 │         │告警路由 │              │ master-auto-    │       │
│  └─────────┘         └─────────┘              │ repair.sh       │       │
│       │                   │                   └────────┬────────┘       │
│       ▼                   ▼                            │                │
│  PrometheusRule      webhook (預留)                    ▼                │
│  (告警規則)          └── n8n 整合                ┌────────────┐         │
│                                                  │ oom-handler │         │
│  ┌─────────┐         ┌─────────┐               │ postgres-   │         │
│  │域名健康  │ ──────▶│Telegram │ ◀─────────────│  repair     │         │
│  │監控腳本 │         │告警通知 │               │ auto-       │         │
│  └─────────┘         └─────────┘               │  rollback   │         │
│  (每5分鐘Cron)                                  └────────────┘         │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

n8n 工作流程更新 (2026-02-13 20:30):

  • 重新匯入所有 27+ 個工作流程到 n8n
  • 停用使用 executeCommand 節點的工作流程 (n8n 2.6.4 不支援)
  • 停用的工作流程改用 Cron 自動修復機制代替:
    • UAT 自動修復 → Cron: domain-health-monitor.sh
    • Clawdbot 健康監控 → Cron: 已整合

Git 提交記錄 (2026-02-13 21:00):

feat: 完整監控告警與自動修復系統

新增自動修復腳本 (scripts/auto-repair/):
- oom-handler.sh: OOM 自動增加記憶體
- postgres-repair.sh: PostgreSQL 自動維護
- auto-rollback.sh: 健康檢查失敗自動回滾
- master-auto-repair.sh: 主協調腳本

新增 Prometheus 告警規則:
- k8s/monitoring/complete-alerting-rules.yaml
- 14 個告警規則覆蓋所有核心服務
- 每個告警都有對應的自動修復標籤

已提交至 Git 版控:


2026-02-09域名健康監控與服務修復

1. 新增域名健康監控腳本

腳本: scripts/domain-health-monitor.sh Cron: 每 5 分鐘執行

功能:

  • 監控 8 個核心域名健康狀態
  • 自動發送 Telegram 告警
  • 嘗試自動修復(重啟容器/K8s Pod
  • 等待 30 秒驗證修復結果

2. 更新 Nginx 配置

檔案: docker/nginx/monitor-clean.conf

變更:

  • 移除 Harbor 相關配置Harbor 已廢棄)
  • 新增 Docker Registry 反向代理port 5002
  • 更新 Prometheus 使用 K8s ClusterIP (10.43.25.78:9090)
  • 更新 Alertmanager 使用 K8s ClusterIP (10.43.79.187:9093)

3. Docker 服務修復

n8n 容器重建:

  • 問題Task Runner 403 錯誤 + 端口綁定問題
  • 修復:添加 N8N_RUNNERS_DISABLED=true 環境變數
  • 重建命令:
docker run -d --name momo-n8n --restart unless-stopped \
  -p 5678:5678 \
  -e N8N_BASIC_AUTH_USER=admin \
  -e N8N_BASIC_AUTH_PASSWORD=Wooo_N8n_2026 \
  -e N8N_RUNNERS_DISABLED=true \
  -v n8n_data:/home/node/.n8n \
  n8nio/n8n:latest

Superset 容器修復:

  • 問題Docker 重啟後容器停止
  • 修復:cd /home/wooo/momo_pro_system/docker/superset && docker compose up -d

4. 當前服務狀態 (2026-02-09 驗證)

正常運作的服務:

服務 URL 狀態碼
EwoooC App (mo) https://mo.wooo.work/health 200
EwoooC App (momo) https://momo.wooo.work/health 200
Monitor 首頁 https://monitor.wooo.work/ 200
Superset https://monitor.wooo.work/superset/login/ 200
Metabase https://monitor.wooo.work/metabase/ 200
n8n http://192.168.0.110:5678/ 200
Registry https://registry.wooo.work/v2/ 401
K8s Grafana https://monitor.wooo.work/k8s-grafana/ 302
Prometheus https://monitor.wooo.work/prometheus/ 302
Alertmanager https://monitor.wooo.work/alertmanager/ 200

未部署的服務:

  • Nextcloud: 無容器
  • Grist: 無容器
  • Docker Grafana: 無容器(使用 K8s Grafana
  • Portainer: 無容器
  • Loki: 無容器
  • cAdvisor: 無容器
  • Blackbox Exporter: 無容器

已知問題:

  • harbor-core 容器卡在 restart loop需 root 權限移除)
  • cattle-cluster-agent CrashLoopBackOffRancher 相關,不影響核心服務)

2026-02-08Superset 子路徑代理修復

1. 修復 Superset 雙重前綴問題

問題:訪問 /superset/ 會跳轉到 /superset/superset/welcome/

根本原因

  • Superset 內部 Flask blueprints 已使用 /superset/... 路由
  • superset_config.pyx_prefix=1 會再次添加前綴
  • Nginx proxy_redirect / /superset/; 也會重複添加

修復方案

  1. superset_config.py: 設置 x_prefix=0 禁用從 X-Forwarded-Prefix 讀取前綴
  2. nginx-superset.conf: 使用智能正則表達式保留已有 /superset/ 前綴
    proxy_redirect /superset/ /superset/;
    proxy_redirect ~^/(?!superset)(.*)$ /superset/$1;
    

2. 修復 Superset 登入重定向問題

問題:訪問 /superset/login/ 後跳轉到 /login/ → 404

根本原因

  • Superset JavaScript bootstrap 資料中 user_login_url: "/login/" 沒有前綴
  • 瀏覽器直接訪問 /login/ 時 Nginx 無法匹配到 Superset

修復方案:在 Nginx 添加多個重定向規則

location = /login/ {
    return 302 /superset/login/;
}
location = /logout/ {
    return 302 /superset/logout/;
}
location ^~ /lang/ {
    return 302 /superset$request_uri;
}
location ^~ /users/ {
    return 302 /superset$request_uri;
}

修改檔案

  • docker/superset/superset_config.py - 設置 x_prefix=0
  • docker/superset/nginx-superset.conf - 更新代理規則和重定向

驗證結果

路徑 狀態
/superset/ 302 → /superset/welcome/
/superset/login/ 200 (登入頁面)
/login/ 302 → /superset/login/
/logout/ 302 → /superset/logout/

2026-02-07CI/CD Dashboard + 移除 Harbor

1. Harbor 完全移除,改用 Docker Registry

變更原因Harbor 資源佔用大、穩定性問題,改用輕量級 Docker Registry

項目 舊配置 新配置
Registry URL harbor.wooo.work registry.wooo.work
Port 5050 5002 (內部) → Nginx 反向代理
認證 Harbor 內建 Nginx Basic Auth
映像路徑 harbor.wooo.work/wooo/momo-pro-system:latest registry.wooo.work/wooo/momo-pro-system:latest

新增/修改檔案

  • docker/registry/docker-compose.yml - Docker Registry 配置
  • docker/registry/config.yml - Registry 儲存配置
  • config/nginx/sites-available/registry - Nginx 反向代理配置

2. CI/CD Dashboard 完整版

URL: https://mo.wooo.work/cicd

功能

  • 即時 Pipeline 流程視覺化Test → Build → Deploy
  • UAT/PROD 環境健康狀態卡片
  • Pod 狀態監控(透過 SSH 查詢)
  • 快速操作按鈕(部署 UAT/PROD、回滾
  • 成功率統計、今日部署次數
  • 10 秒自動刷新

新增檔案

  • routes/cicd_routes.py - CI/CD API 路由 (1354 行)
  • templates/cicd_dashboard.html - Dashboard 前端頁面

API 端點

端點 方法 說明
/api/cicd/status GET 取得完整 CI/CD 狀態
/api/cicd/pipelines GET 取得最近 Pipeline 列表
/api/cicd/environments GET 取得所有環境狀態
/api/cicd/deploy/<env> POST 觸發部署
/api/cicd/rollback/<env> POST 回滾部署

3. CI/CD UAT 自動部署(歷史紀錄)

2026-04-18 備註: 當時的 CI/CD 建構在 GitLab CI 之上GitLab 已撤除,以下內容僅作歷史參考。

當時流程push main → UAT 自動部署

當時 Pipeline 階段

push main
    │
    ├─ test (pytest)
    ├─ security-scan (Bandit)
    │
    ├─ build (docker build + push to registry.wooo.work)
    │
    └─ deploy-uat (SSH → git pull → kubectl restart)

4. 監控告警標籤

Alertmanager (Prometheus) 告警模板

🏢 <b>環境:</b> <code>UAT</code> (mo.wooo.work)

n8n 頁面健康監控

  • UAT 監控:n8n-workflows/17-page-health-monitor.json
    • 告警標題:🔴 *EwoooC 頁面異常*
    • 標籤:(mo.wooo.work / momo.wooo.work)

5. wooo 用戶 kubectl 無密碼訪問設定

# 設定 kubeconfig
sudo cp /etc/rancher/k3s/k3s.yaml /home/wooo/.kube/config
sudo chown wooo:wooo /home/wooo/.kube/config

# 加入 bashrc
echo 'export KUBECONFIG=/home/wooo/.kube/config' >> ~/.bashrc

修改檔案清單

  • app.py - 註冊 CI/CD Blueprint
  • routes/cicd_routes.py - 新增
  • templates/cicd_dashboard.html - 新增
  • n8n-workflows/17-page-health-monitor.json - 環境標籤
  • k8s/monitoring/values-prometheus.yaml - Alertmanager 環境標籤

6. PostgreSQL 監控部署 (新增)

部署內容

  • k8s/monitoring/postgres-exporter.yaml - PostgreSQL Exporter Deployment + ServiceMonitor
  • k8s/monitoring/postgres-alerting-rules.yaml - 資料庫告警規則

監控指標

指標 閾值 告警等級
連線數 > 80 Warning
連線數 > 95 Critical
資料庫停機 pg_up == 0 Critical
資料庫大小 > 5GB Warning
資料庫大小 > 8GB Critical
死鎖 > 0 Warning
表膨脹 (Dead Tuples) > 100,000 Warning

7. n8n 工作流程匯入完成 (22個)

原有工作流程 (20個)

  • 系統監控磁碟空間、SSL 證書、CI/CD 通知、備份、爬蟲、K8s Pod、Harbor
  • 定期報告:每日系統報告、每週業績、月初提醒
  • AI 監控Ollama 健康、K8s 健康、慢查詢

新增工作流程 (2個)

  • 17-uat-health-monitor.json - UAT 健康監控
  • 18-postgres-health-monitor.json - PostgreSQL 資料庫監控

工作流程匯入方式

docker exec momo-n8n n8n import:workflow --input=/home/node/n8n-workflows/<file>.json

8. 集中式監控架構

架構決策:所有監控告警統一由 UAT 主機管理

┌─────────────────────────────────────────────────────────────────┐
│                    UAT 主機 (192.168.0.110)                     │
│                      統一監控與排程中心                          │
├─────────────────────────────────────────────────────────────────┤
│  Prometheus → Alertmanager → Telegram                          │
│  n8n 工作流程                                                   │
│  • 監控 EwoooC App (mo.wooo.work / momo.wooo.work)              │
│  • PostgreSQL 健康檢查                                          │
└─────────────────────────────────────────────────────────────────┘

分工原則

類型 工具 位置
監控告警 Prometheus + n8n UAT 集中管理
業務排程 momo-scheduler K8s 內執行

2026-02-02監控系統修復與安全加固

修復項目

1. K8s Scheduler CrashLoopBackOff 修復

  • 問題momo-scheduler Pod 重啟 387 次,持續 CrashLoopBackOff
  • 原因run_scheduler.py 檔案遺失
  • 解決:建立新的 run_scheduler.py 獨立排程腳本
  • 新增檔案run_scheduler.py
# run_scheduler.py 排程任務
- 每小時主站爬蟲EDM 爬蟲
-  6 小時購物節爬蟲
-  30 分鐘Google Drive 自動匯入網頁白頁監控

2. vendor-stockout 500 錯誤修復

  • 問題:訪問 /vendor-stockout/ 返回 Internal Server Error
  • 原因:模板位置錯誤 (vendor_stockout_index.html 應為 templates/vendor_stockout/index.html)
  • 解決:建立 templates/vendor_stockout/ 目錄並移動所有模板
templates/vendor_stockout/
├── index.html
├── list.html
├── history.html
├── import.html
├── send_email.html
└── vendor_management.html

3. Alertmanager 無法發送 Telegram 告警修復

  • 問題Alertmanager 日誌持續報錯 can't evaluate field StartsAt in type *template.Data
  • 原因Telegram 訊息模板錯誤,.StartsAt 放在 {{ range .Alerts }} 區塊外
  • 解決:修正模板,將 .StartsAt 移入 range 區塊內
  • 修改檔案k8s/monitoring/values-prometheus.yaml
# 修正前(錯誤)
{{ range .Alerts }}...{{ end }}
⏰ <i>時間: {{ .StartsAt.Local.Format "..." }}</i>  # 錯誤:在 range 外

# 修正後(正確)
{{ range .Alerts }}
...
⏰ <i>時間: {{ .StartsAt.Local.Format "..." }}</i>  # 正確:在 range 內
{{ end }}

4. n8n 配置損壞修復

  • 問題n8n 容器持續重啟,配置檔案損壞
  • 解決:重新寫入正確的 JSON 配置

5. 伺服器安全加固

192.168.0.188 (Ollama Server)

  • 安裝 Fail2Ban (SSH 3 次失敗封鎖 1 小時)
  • 安裝 UFW 防火牆
  • AI 服務限制內網存取 (192.168.0.0/24)

192.168.0.110 (UAT Server)

  • Fail2Ban 已運行 (確認配置正確)
  • SSH + Nginx 雙重保護

UFW 規則 (192.168.0.188)

端口 服務 存取範圍
22 SSH 公開
80/443 HTTP/HTTPS 公開
11434 Ollama API 僅內網
3000 Open WebUI 僅內網
5678 n8n 僅內網
8080 SearXNG 僅內網

監控系統現況

Prometheus (抓取指標) → PrometheusRule (告警規則) → Alertmanager → Telegram Bot

目前告警規則:

  • PodOOMKilled, PodRestartTooMany, PodNotReady, PodPending
  • HighMemoryUsage, MemoryNearLimit, HighCPUUsage
  • PostgresDown, PVCSpaceLow
  • MomoAppDown, HighHTTP5xxRate
  • NodeMemoryLow, NodeDiskLow, NodeNotReady

2026-01-31系統重開機自動啟動機制

問題發現

  • 伺服器重開機後 Registry 容器未正常啟動 (Exit 128)
  • K8s Pod 顯示 ImagePullBackOff 無法拉取映像
  • mo.wooo.work 返回 502 Bad Gateway
  • 系統負載過高 (load average 112)

根本原因

  1. Registry 容器重開機後未自動啟動
  2. Supabase 不必要服務佔用大量資源
  3. 沒有統一的服務啟動順序管理

解決方案

  1. 建立 scripts/tools/system_startup.sh 統一啟動腳本
  2. 建立 momo-startup.service systemd 服務
  3. 啟動順序Docker → 停止 Supabase 多餘服務 → Registry → K8s → 監控
  4. 每個服務啟動後進行健康檢查
  5. 啟動完成後發送 Telegram 通知

新增檔案

  • scripts/tools/system_startup.sh - 系統啟動腳本
  • scripts/tools/momo-startup.service - systemd 服務定義
  • deploy/lib/registry.sh - Registry 管理函數庫
  • deploy/lib/k8s.sh - K8s 管理函數庫
  • deploy/lib/monitoring.sh - 監控與通知函數庫
  • deploy/lib/systemd.sh - Systemd 服務管理函數庫

部署步驟

# 1. 上傳腳本
scp scripts/tools/system_startup.sh wooo@192.168.0.110:/home/wooo/momo_pro_system/scripts/tools/

# 2. 安裝 systemd 服務
sudo cp /tmp/momo-startup.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable momo-startup.service

驗證方式

# 確認服務已啟用
systemctl is-enabled momo-startup.service  # 應返回 enabled

# 查看啟動日誌
sudo journalctl -u momo-startup.service

2026-01-28502 Bad Gateway 排查與自動修復

問題發現

  • mo.wooo.work 返回 502 Bad Gateway
  • Nginx 無法連接到後端 Docker 容器

排查過程

  1. 檢查 Docker 容器狀態 → 顯示 healthy
  2. 測試外部端口 curl 127.0.0.1:5001 → Connection reset by peer
  3. 測試容器內部 docker exec curl → HTTP 200 正常
  4. 診斷結論Docker 網路轉發失效

解決方案

sudo systemctl restart docker

新增功能

  • 新增自動化監控腳本 scripts/docker_health_monitor.sh
  • 每 5 分鐘自動檢查服務健康狀態
  • 檢測到 Docker 網路問題時自動修復
  • 發送 Telegram 告警通知

修改檔案

  • CLAUDE.md - 新增問題 #4, #5 和自動修復文檔
  • scripts/docker_health_monitor.sh - Docker 網路監控腳本
  • scripts/registry_health_monitor.sh - Registry 服務監控腳本
  • k8s/04-momo-app.yaml - 改用 registry.wooo.work 域名
  • k8s/05-scheduler.yaml - 改用 registry.wooo.work 域名

2026-01-28Registry 服務中斷與 K8s 映像拉取修復

問題發現

  • Google Drive 自動匯入功能停止
  • K8s Pods 顯示 ImagePullBackOff

根本原因

  1. Docker Registry 服務停止
  2. Registry 端口綁定 127.0.0.1:5000安全配置
  3. K8s 嘗試從 192.168.0.110:5000 拉取映像失敗

解決方案

  1. 啟動 Registry: cd /home/wooo/devops/registry && docker compose up -d
  2. K8s 配置改用 HTTPS 域名 registry.wooo.work
  3. 重建 registry secret 使用新域名
  4. 重啟 K8s Deployments

預防措施

  • 建立 Registry 健康監控腳本
  • 加入 cron 排程自動檢查
  • UAT crontab - 新增排程任務

2026-01-28當日業績匯入 OOM 問題修復

問題發現

  • 自動匯入通知發送成功,但 /daily_sales 頁面顯示「資料表為空」
  • 匯入任務卡在 60% 進度

排查過程

  1. 檢查 import_jobs 表發現任務狀態為 importing,進度 60%
  2. 查看 Docker 日誌發現 Worker was sent SIGKILL! Perhaps out of memory?
  3. 確認 OOM 導致匯入進程被殺死

解決方案

  1. 找到暫存檔案 /app/data/temp/即時業績_當日.xlsx(匯入中途失敗但已下載)
  2. 手動觸發匯入:
    from services.import_service import import_service
    import os
    file_path = '/app/data/temp/即時業績_當日.xlsx'
    job_id = import_service.create_import_job('daily_sales', None, '即時業績_當日.xlsx', os.path.getsize(file_path))
    import_service.process_daily_sales_import(job_id, file_path)
    
  3. 成功匯入 19,099 筆資料2026-01-01 ~ 2026-01-27

資料流向說明(重要)

Excel 檔案 → import_service.process_daily_sales_import()
                    │
                    ├→ daily_sales_snapshot (主資料表77欄位含 snapshot_date)
                    │
                    └→ realtime_sales_monthly (副本28欄位供業績分析儀表板)
  • 正確方向daily_sales_snapshotrealtime_sales_monthly(同步寫入)
  • 禁止反向操作:不可從 realtime_sales_monthly 同步回 daily_sales_snapshot

修改檔案

  • services/import_service.py - 新增日期範圍追蹤
  • scheduler.py - 增強匯入通知格式
  • scripts/google_drive_monitor.sh - Google Drive 認證監控
  • scripts/system_health_monitor.sh - 統一健康監控腳本

2026-01-28Ollama 502 Bad Gateway 修復與監控機制

問題發現

  • http://192.168.0.188/ 返回 502 Bad Gateway
  • Ollama API http://192.168.0.188:11434/api/tags 正常回應

診斷過程

  1. 檢查 nginx 進程 → 正常運行
  2. 檢查 nginx error.log → recv() failed (104: Unknown error) 指向 127.0.0.1:3000
  3. 發現 nginx 代理到 Open WebUI 容器 (port 3000),非直接代理 Ollama
  4. 檢查 Open WebUI 容器 → 容器內部正常,但外部無法連接
  5. 診斷結論:Docker 端口映射失效

解決方案

ssh ollama@192.168.0.188
sudo systemctl restart docker
# 等待 60 秒後所有容器恢復

新增監控機制

  • 監控腳本: scripts/ollama_health_monitor.sh
  • n8n 工作流程: n8n-workflows/14-ollama-health-monitor.json
  • 排程: 每 5 分鐘執行 (cron)
  • 自動修復:
    • Open WebUI 502 → 重啟 Docker daemon
    • Open WebUI 容器卡住 → 重啟容器
    • Nginx 停止 → 重啟 nginx
    • Ollama 停止 → 重啟 Ollama

部署到 192.168.0.188:

# 1. 上傳監控腳本
scp scripts/ollama_health_monitor.sh ollama@192.168.0.188:/home/ollama/scripts/

# 2. 設定 cron
*/5 * * * * /home/ollama/scripts/ollama_health_monitor.sh >> /var/log/ollama_health_monitor.log 2>&1

# 3. 設定 sudoers無密碼重啟
ollama ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart docker, /usr/bin/systemctl restart nginx, /usr/bin/systemctl restart ollama

修改檔案

  • scripts/ollama_health_monitor.sh - 新增 Ollama/Open WebUI 監控腳本
  • n8n-workflows/14-ollama-health-monitor.json - 新增 n8n 工作流程
  • CLAUDE.md - 更新 Ollama 監控文檔

2026-01-25DevSecOps 安全強化 + WireGuard VPN

Registry 安全配置

  • 端口 5000 改為僅綁定 127.0.0.1 (內部)
  • 外部訪問改用 registry.wooo.work (HTTPS)
  • CI/CD 腳本更新使用域名
  • 減少攻擊面

WireGuard VPN (WG-Easy)

  • 部署於 Kali Linux (192.168.0.112)
  • 管理介面:http://192.168.0.112:51821
  • 外部端點:114.32.151.246:51820/udp
  • QR Code 掃描連線

CI/CD 安全掃描(已退役,待新方案重建)

  • 曾在 GitLab CI 上設置 security-code-scan(每次 Push 執行 Banditcontainer-security-scan(每週 Trivy 容器弱點掃描)
  • 掃描結果自動發送 Telegram 通知
  • 隨 GitLab 撤除而停用,後續需在新 CI/CD 平台重建

SSL/TLS 安全審核 (SSLyze)

  • mo.wooo.work 掃描結果: 全部通過
  • SSL 2.0/3.0, TLS 1.0/1.1 已禁用
  • TLS 1.2/1.3 啟用強加密套件
  • HSTS 已啟用,無 Heartbleed/CRIME 弱點

Trivy 容器掃描結果

  • 掃描 192.168.0.110:5050/wooo/momo-pro-system:latest
  • HIGH: 56 (Debian 基礎映像)
  • CRITICAL: 0
  • Python 套件: 0 弱點

Kali Linux DevSecOps 工作站 (192.168.0.112)

  • 建立集中式安全掃描環境
  • 部署 port_monitor.pyNmap 端口監控,每小時執行
  • 部署 code_security_scan.pyBandit 程式碼掃描,每日執行
  • 建立端口基線9 個端口 (192.168.0.110: 7, 192.168.0.188: 2)
  • 程式碼掃描結果16 HIGH, 65 MEDIUM, 72 LOW

2026-01-24K8s 配置優化 + Rancher 部署

K8s Google Drive 認證修復

  • 問題K8s Secret 為唯讀OAuth Token 無法刷新
  • 解法:使用 initContainer 將認證複製到 emptyDir可寫入
  • 修改檔案:k8s/04-momo-app.yamlk8s/05-scheduler.yaml
  • 新增 Secretgoogle-drive-credentials

Ollama AI 配置更新

  • Host 更新為 http://192.168.0.188:11434(原本錯誤指向 192.168.0.110
  • 模型更新為 llama3:70b-instruct-q2_K
  • 修改檔案:k8s/02-configmap.yaml

n8n 白頁修復

  • 問題:子路徑 /n8n/ 顯示空白頁面
  • 解法:新增環境變數 N8N_PATH_PREFIX=/n8n
  • 修改檔案UAT docker-compose.yml

Rancher 部署 + K3s 匯入

  • 安裝 Rancher v2.13.1 via Docker
  • URLhttps://192.168.0.110:8443
  • K3s 集群 momo-k3s 已成功匯入
  • Cluster IDc-52mz8
  • 修改檔案:k8s/nginx/monitor.conf(新增 /rancher/ 代理)

2026-01-24K8s 遷移完成

重大變更

  • K3s 部署完成 - 版本 v1.34.3+k3s1
  • PostgreSQL 資料遷移完成 - 資料庫: momo_analytics
  • VM Nginx 配置更新 - 指向 K8s ClusterIP

K8s 資源

資源 說明
momo-app Flask 應用 Deployment
momo-postgres PostgreSQL StatefulSet
momo-scheduler 爬蟲排程 Deployment
momo-data-pvc 應用資料 PVC (5Gi)
postgres-pvc 資料庫 PVC (10Gi)

網路架構

用戶 → mo.wooo.work:443 → VM Nginx (SSL) → K8s ClusterIP 10.43.238.49:80 → momo-app

備份位置

  • /home/wooo/backups/pre-k8s-migration/
  • 回滾腳本: quick_rollback.sh

2026-01-22CI/CD 初版部署(已退役)

2026-04-18 備註: 原本以 GitLab CE + Docker Registry + Watchtower 為核心的 CI/CD 架構已撤除此段僅作歷史紀錄。Docker Registry 與 Watchtower 仍保留在 UAT 運作。

當時架構重點

  • 自建 Git 伺服器 + CI/CD 平台(已撤除)
  • Docker Registry: 私有 Container Registry保留位於 registry.wooo.work
  • Watchtower: 自動偵測 Registry 映像更新並部署(保留)
  • 部署位置: UAT Server (192.168.0.110)

當時 CI/CD 流程

git push → CI 測試 → 構建 Docker Image → 推送到 Registry → Watchtower 自動更新容器

2026-01-22PostgreSQL 相容性修復

問題sales_analysis 頁面的「星期幾」和「時段」篩選功能在 PostgreSQL 環境下失效

原因SQLite 使用 strftime('%w', timestamp) 取得星期幾PostgreSQL 使用 EXTRACT(dow FROM timestamp)

修復內容

  1. 更新 app.py 中的 get_sales_table_data() 函數
  2. 根據 DATABASE_TYPE 動態選擇正確的 SQL 語法
  3. 修復 SQLite 日期字串格式問題PostgreSQL 返回 datetime 物件)

修改檔案

  • app.py (約 line 2800-2900)
  • config.py - 新增 DATABASE_TYPE 變數

驗證API /api/sales_table?dow=1&hour=14 在 PostgreSQL 環境正常運作


2026-01-23商品看板效能優化

問題:商品看板首頁載入緩慢(約 3-4 秒)

診斷結果

  • 資料庫有 5,510 商品、609,173 價格記錄
  • price_records 表缺少 product_id 索引
  • 多個 gunicorn worker 同時重建快取

優化措施

1. PostgreSQL 索引優化

CREATE INDEX CONCURRENTLY idx_price_records_product_id ON price_records(product_id);
CREATE INDEX CONCURRENTLY idx_price_records_product_timestamp ON price_records(product_id, timestamp DESC);
CREATE INDEX idx_products_status ON products(status);

2. 跨進程快取鎖定FileLock

  • threading.Lock() 替換為 fcntl.flock() 檔案鎖
  • 解決多 gunicorn worker 同時重建快取的問題
  • 鎖定檔案位置:data/.dashboard_cache.lock

修改檔案

  • routes/dashboard_routes.py - 新增 FileLock 類別,更新 get_full_dashboard_data() 函數

效能改善

情境 優化前 優化後
快取命中 ~1 秒 ~1 秒
快取重建(單一 worker ~3-4 秒 ~3-4 秒
快取重建(多 worker 每個各 3-4 秒 只有一個重建

FileLock 實作細節

import fcntl

class FileLock:
    """簡單的檔案鎖,用於 gunicorn 多進程環境"""
    def __init__(self, lock_file):
        self.lock_file = lock_file
        self.fd = None

    def acquire(self, blocking=True):
        try:
            self.fd = open(self.lock_file, 'w')
            if blocking:
                fcntl.flock(self.fd, fcntl.LOCK_EX)
            else:
                fcntl.flock(self.fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
            return True
        except (IOError, OSError):
            if self.fd:
                self.fd.close()
                self.fd = None
            return False

    def release(self):
        if self.fd:
            fcntl.flock(self.fd, fcntl.LOCK_UN)
            self.fd.close()
            self.fd = None

使用方式

_DASHBOARD_FILE_LOCK = FileLock('/path/to/data/.dashboard_cache.lock')

# 取得鎖(非阻塞)
if not _DASHBOARD_FILE_LOCK.acquire(blocking=False):
    # 其他 worker 正在重建,等待
    _DASHBOARD_FILE_LOCK.acquire()
    _DASHBOARD_FILE_LOCK.release()
    return cached_data

try:
    # 重建快取...
finally:
    _DASHBOARD_FILE_LOCK.release()

資料庫表結構

核心業務表

  • daily_sales_snapshot - 每日銷售快照 (snapshot_date 欄位)
  • realtime_sales_monthly - 業績分析儀表板資料 (日期 欄位)
  • products - 商品資料
  • price_records - 價格記錄

廠商缺貨系統

  • vendor_stockout - 缺貨商品清單
  • vendor_list - 廠商資料
  • vendor_emails - 廠商郵件地址
  • email_send_log - 郵件發送記錄

系統表

  • users - 用戶帳號
  • permissions - 權限定義
  • user_permissions - 用戶權限關聯
  • import_jobs - 匯入任務記錄
  • import_config - 匯入設定

部署指令(Docker-on-188,見 ADR-008)

SSH 進入 188(必經 110 跳板)

ssh -J wooo@192.168.0.110 ollama@192.168.0.188

同步 Python 檔案到 188(volume mount,即時生效)

# 經 110 跳板
scp -o ProxyJump=wooo@192.168.0.110 app.py ollama@192.168.0.188:/home/ollama/momo-pro/
scp -o ProxyJump=wooo@192.168.0.110 -r services/ ollama@192.168.0.188:/home/ollama/momo-pro/

重啟主應用(volume mount 後)

ssh -J wooo@192.168.0.110 ollama@192.168.0.188 "docker restart momo-pro-system"

重建映像(新增套件 / Dockerfile 變更)

ssh -J wooo@192.168.0.110 ollama@192.168.0.188 "cd /home/ollama/momo-pro && docker compose build momo-app && docker compose up -d momo-app"

查看日誌

# momo-pro-system
ssh -J wooo@192.168.0.110 ollama@192.168.0.188 "docker logs -f momo-pro-system --tail 100"

# scheduler
ssh -J wooo@192.168.0.110 ollama@192.168.0.188 "docker logs -f momo-scheduler --tail 100"

# PostgreSQL (pgvector)
ssh -J wooo@192.168.0.110 ollama@192.168.0.188 "docker logs -f momo-db --tail 100"

進入容器 Shell

# 進入主應用
ssh -J wooo@192.168.0.110 ollama@192.168.0.188 "docker exec -it momo-pro-system /bin/bash"

# 進入 PostgreSQL(pgvector/pg14)
ssh -J wooo@192.168.0.110 ollama@192.168.0.188 "docker exec -it momo-db psql -U momo -d momo_analytics"

待辦:細粒度權限系統實作計畫

需求總結

將現有的三級角色權限系統 (admin/manager/user) 升級為細粒度權限配置系統:

  • 保留角色概念:作為「預設權限模板」,新增用戶時快速套用
  • 權限粒度:分為「查看」和「操作」兩層
  • 不需要權限群組功能

現有系統分析

已有的基礎設施

檔案 說明
database/user_models.py User 和 LoginHistory 模型已存在
services/user_service.py 用戶 CRUD 服務已存在
services/password_service.py 密碼服務已存在
routes/user_routes.py 用戶管理路由已存在
templates/user_management.html 用戶管理頁面已存在
auth.py login_required, role_required 裝飾器已存在

需要擴展的部分

  • User 模型需新增 permissions 欄位或關聯表
  • 新增 Permission 模型和 UserPermission 關聯表
  • 新增 permission_required 裝飾器
  • 更新用戶管理介面,增加權限勾選區塊
  • 更新導航列,根據權限動態顯示選單

資料庫設計

新增表: permissions (權限定義表)

class Permission(db.Model):
    """權限定義表 - 系統預設,不可刪除"""
    __tablename__ = 'permissions'

    id = Column(Integer, primary_key=True)
    code = Column(String(50), unique=True, nullable=False)  # 如 'dashboard.view'
    name = Column(String(100), nullable=False)              # 顯示名稱 '查看首頁看板'
    category = Column(String(50), nullable=False)           # 分類 '首頁/看板'
    description = Column(String(200))                       # 詳細說明
    sort_order = Column(Integer, default=0)                 # 排序順序

新增表: user_permissions (用戶權限關聯表)

class UserPermission(db.Model):
    """用戶權限關聯表"""
    __tablename__ = 'user_permissions'

    id = Column(Integer, primary_key=True)
    user_id = Column(Integer, ForeignKey('users.id'), nullable=False)
    permission_code = Column(String(50), nullable=False)
    granted_by = Column(Integer, ForeignKey('users.id'))
    granted_at = Column(DateTime, default=datetime.utcnow)

    # 複合唯一索引
    __table_args__ = (
        UniqueConstraint('user_id', 'permission_code', name='uq_user_permission'),
    )

權限清單定義

首頁/看板

權限代碼 名稱 說明
dashboard.view 查看首頁看板 訪問 / 首頁
dashboard.export 匯出看板資料 匯出商品資料 Excel

報表

權限代碼 名稱 說明
report.daily_sales.view 查看每日銷售 訪問 /daily_sales
report.daily_sales.export 匯出每日銷售 匯出每日銷售 Excel
report.monthly_summary.view 查看月度總結 訪問 /monthly_summary_analysis
report.monthly_summary.import 匯入月度資料 匯入月度總結 Excel
report.sales_analysis.view 查看銷售分析 訪問 /sales_analysis
report.growth_analysis.view 查看成長分析 訪問 /growth_analysis
report.abc_analysis.view 查看 ABC 分析 訪問 /abc_analysis/detail

活動看板

權限代碼 名稱 說明
edm.view 查看 EDM 看板 訪問 /edm
edm.trigger 觸發 EDM 爬蟲 手動觸發爬蟲按鈕
festival.view 查看節慶看板 訪問 /festival
festival.trigger 觸發節慶爬蟲 手動觸發爬蟲按鈕

廠商缺貨

權限代碼 名稱 說明
vendor.index.view 查看廠商缺貨首頁 訪問 /vendor_stockout/
vendor.import 匯入缺貨資料 匯入缺貨 Excel
vendor.list.view 查看缺貨清單 訪問 /vendor_stockout/list
vendor.list.edit 編輯缺貨資料 編輯/刪除缺貨記錄
vendor.management.view 查看廠商管理 訪問 /vendor_stockout/vendor-management
vendor.management.edit 管理廠商資料 新增/編輯/刪除廠商
vendor.email.view 查看郵件發送 訪問 /vendor_stockout/send-email
vendor.email.send 發送廠商郵件 發送缺貨通知郵件
vendor.history.view 查看歷史記錄 訪問 /vendor_stockout/history

匯入

權限代碼 名稱 說明
import.auto.view 查看自動匯入 訪問 /auto_import
import.auto.manage 管理匯入任務 新增/編輯/刪除任務
import.manual 手動匯入資料 系統設定頁匯入按鈕

系統

權限代碼 名稱 說明
system.settings.view 查看系統設定 訪問 /settings
system.settings.edit 修改系統設定 儲存設定變更
system.advanced.view 查看進階設定 訪問 /system_settings
system.advanced.edit 修改進階設定 分類管理等
system.logs.view 查看系統日誌 訪問 /logs
system.crawler.view 查看爬蟲管理 訪問 /crawler_management
system.crawler.manage 管理爬蟲設定 修改爬蟲設定
system.backup 備份資料庫 執行備份操作
system.users.view 查看用戶管理 訪問 /user_management
system.users.manage 管理用戶帳號 新增/編輯/刪除用戶

其他

權限代碼 名稱 說明
brand_assets.view 查看品牌素材 訪問 /brand_assets

總計: 31 個權限項目


角色預設權限模板

admin (管理員)

  • 全部 31 個權限

manager (管理者)

  • 所有 .view 權限
  • dashboard.export
  • report.daily_sales.export
  • report.monthly_summary.import
  • vendor.import, vendor.list.edit, vendor.management.edit, vendor.email.send
  • import.auto.manage, import.manual
  • system.settings.edit
  • 排除: system.users.*, system.backup, system.advanced.edit, system.crawler.manage

user (一般用戶)

  • dashboard.view
  • report.daily_sales.view, report.monthly_summary.view, report.sales_analysis.view, report.growth_analysis.view, report.abc_analysis.view
  • edm.view, festival.view
  • vendor.index.view, vendor.list.view, vendor.history.view

修改檔案清單

新增檔案

檔案 說明
database/permission_models.py Permission 和 UserPermission 模型
services/permission_service.py 權限 CRUD 服務、角色模板應用
templates/user_permissions.html 用戶權限編輯頁面 (獨立頁面或 Modal)

修改檔案

檔案 修改內容
auth.py 新增 permission_required 裝飾器、更新 get_current_user()
routes/user_routes.py 新增權限 CRUD API
templates/user_management.html 新增「編輯權限」按鈕
app.py 註冊權限 context_processor、初始化權限資料
database/manager.py 新增權限表初始化

需更新權限檢查的路由檔案

檔案 說明
routes/dashboard_routes.py 首頁看板
routes/daily_sales_routes.py 每日銷售
routes/monthly_routes.py 月度總結
routes/sales_routes.py 銷售分析、成長分析
routes/edm_routes.py EDM、節慶看板
routes/system_routes.py 系統設定、日誌
vendor_routes.py 廠商缺貨相關
auto_import_routes.py 自動匯入
crawler_management_routes.py 爬蟲管理

實作步驟

Phase 1: 資料庫模型 (預計 1 步)

  1. 建立 database/permission_models.py

    • Permission 模型
    • UserPermission 模型
    • 權限常數定義 (PERMISSIONS 字典)
    • 角色預設權限模板 (ROLE_DEFAULT_PERMISSIONS)
  2. 更新 database/manager.py

    • init_db() 中初始化權限表資料

Phase 2: 服務層 (預計 1 步)

  1. 建立 services/permission_service.py
    • get_all_permissions() - 取得所有權限定義 (分類顯示)
    • get_user_permissions(user_id) - 取得用戶權限列表
    • set_user_permissions(user_id, permission_codes, granted_by) - 設定用戶權限
    • apply_role_template(user_id, role) - 套用角色預設權限
    • has_permission(user_id, permission_code) - 檢查是否有權限
    • has_any_permission(user_id, *permission_codes) - 檢查是否有任一權限

Phase 3: 認證與裝飾器 (預計 1 步)

  1. 更新 auth.py
    • 新增 permission_required(*permissions) 裝飾器
    • 更新 get_current_user() 增加 permissions 欄位
    • 登入時載入用戶權限到 session (或每次查詢)

Phase 4: API 路由 (預計 1 步)

  1. 更新 routes/user_routes.py
    • GET /api/permissions - 取得所有權限定義
    • GET /api/users/<user_id>/permissions - 取得用戶權限
    • PUT /api/users/<user_id>/permissions - 更新用戶權限
    • POST /api/users/<user_id>/apply_role_template - 套用角色模板

Phase 5: 前端介面 (預計 1 步)

  1. 建立用戶權限編輯介面
    • 可在 user_management.html 新增 Modal 或獨立頁面
    • 按分類顯示權限勾選框
    • 「套用角色模板」下拉選單
    • 「全選」/「清除」按鈕

Phase 6: 套用權限檢查 (預計 2-3 步)

  1. 更新各路由檔案,將 @role_required 改為 @permission_required
  2. 更新導航列模板,根據權限動態顯示選單項目
  3. 更新頁面內的操作按鈕,根據權限顯示/隱藏

Phase 7: 測試驗證 (預計 1 步)

  1. 建立測試用戶並配置不同權限
  2. 驗證各頁面和功能的權限控制
  3. 確認角色模板套用正確

權限裝飾器設計

def permission_required(*permissions):
    """權限檢查裝飾器

    使用範例:
        @permission_required('dashboard.view')
        @permission_required('vendor.list.view', 'vendor.list.edit')
    """
    def decorator(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            if not session.get('logged_in'):
                return redirect(url_for('login'))

            user_id = session.get('user_id')
            user_role = session.get('role')

            # admin 擁有所有權限
            if user_role == 'admin':
                return f(*args, **kwargs)

            # 檢查用戶是否有任一所需權限
            from services.permission_service import PermissionService
            if not PermissionService.has_any_permission(user_id, *permissions):
                abort(403)

            return f(*args, **kwargs)
        return decorated_function
    return decorator

用戶權限編輯介面設計

┌─────────────────────────────────────────────────┐
│  編輯權限: peter (Peter Chen)                    │
├─────────────────────────────────────────────────┤
│  快速設定: [套用角色模板 ▼]  [全選] [清除]        │
├─────────────────────────────────────────────────┤
│                                                 │
│  📊 首頁/看板                                   │
│  ├─ ☑ 查看首頁看板                              │
│  └─ ☐ 匯出看板資料                              │
│                                                 │
│  📈 報表                                        │
│  ├─ ☑ 查看每日銷售                              │
│  ├─ ☐ 匯出每日銷售                              │
│  ├─ ☑ 查看月度總結                              │
│  ├─ ☐ 匯入月度資料                              │
│  ├─ ☑ 查看銷售分析                              │
│  ├─ ☑ 查看成長分析                              │
│  └─ ☐ 查看 ABC 分析                             │
│                                                 │
│  📣 活動看板                                    │
│  ├─ ☑ 查看 EDM 看板                             │
│  ├─ ☐ 觸發 EDM 爬蟲                             │
│  ├─ ☑ 查看節慶看板                              │
│  └─ ☐ 觸發節慶爬蟲                              │
│                                                 │
│  🏭 廠商缺貨                                    │
│  ├─ ☐ 查看廠商缺貨首頁                          │
│  ├─ ☐ 匯入缺貨資料                              │
│  ├─ ☐ 查看缺貨清單                              │
│  ├─ ☐ 編輯缺貨資料                              │
│  ├─ ☐ 查看廠商管理                              │
│  ├─ ☐ 管理廠商資料                              │
│  ├─ ☐ 查看郵件發送                              │
│  ├─ ☐ 發送廠商郵件                              │
│  └─ ☐ 查看歷史記錄                              │
│                                                 │
│  📥 匯入                                        │
│  ├─ ☐ 查看自動匯入                              │
│  ├─ ☐ 管理匯入任務                              │
│  └─ ☐ 手動匯入資料                              │
│                                                 │
│  ⚙️ 系統                                        │
│  ├─ ☐ 查看系統設定                              │
│  ├─ ☐ 修改系統設定                              │
│  ├─ ☐ 查看進階設定                              │
│  ├─ ☐ 修改進階設定                              │
│  ├─ ☐ 查看系統日誌                              │
│  ├─ ☐ 查看爬蟲管理                              │
│  ├─ ☐ 管理爬蟲設定                              │
│  ├─ ☐ 備份資料庫                                │
│  ├─ ☐ 查看用戶管理                              │
│  └─ ☐ 管理用戶帳號                              │
│                                                 │
│  📦 其他                                        │
│  └─ ☑ 查看品牌素材                              │
│                                                 │
├─────────────────────────────────────────────────┤
│              [取消]  [儲存權限]                   │
└─────────────────────────────────────────────────┘

導航列動態顯示

更新 templates/components/_navbar.html,根據權限決定顯示哪些選單項目:

{% if has_permission('dashboard.view') %}
<a class="nav-link" href="/">首頁</a>
{% endif %}

{% if has_permission('report.daily_sales.view') %}
<a class="nav-link" href="/daily_sales">每日銷售</a>
{% endif %}

{# 廠商缺貨子選單 - 有任一權限就顯示 #}
{% if has_any_permission('vendor.index.view', 'vendor.list.view', 'vendor.management.view') %}
<li class="nav-item dropdown">
    <a class="nav-link dropdown-toggle" href="#">廠商缺貨</a>
    <ul class="dropdown-menu">
        {% if has_permission('vendor.index.view') %}
        <li><a class="dropdown-item" href="/vendor_stockout/">首頁</a></li>
        {% endif %}
        ...
    </ul>
</li>
{% endif %}

驗證計畫

  1. 資料庫測試

    • 確認 permissions 和 user_permissions 表正確建立
    • 確認初始權限資料正確載入
  2. API 測試

    • 取得權限列表 API
    • 更新用戶權限 API
    • 套用角色模板 API
  3. 權限控制測試

    • 建立測試用戶,僅給予 dashboard.viewreport.daily_sales.view
    • 確認可以訪問首頁和每日銷售
    • 確認無法訪問廠商缺貨、系統設定等頁面 (403)
    • 確認導航列只顯示有權限的選單
  4. 角色模板測試

    • 套用 manager 模板,確認權限正確
    • 套用 user 模板,確認權限正確

關鍵檔案路徑

  • 新增: database/permission_models.py
  • 新增: services/permission_service.py
  • 修改: auth.py (新增裝飾器)
  • 修改: routes/user_routes.py (新增 API)
  • 修改: templates/user_management.html (新增權限編輯)
  • 修改: app.py (context_processor)
  • 修改: 各路由檔案 (套用權限檢查)

專案憲法 (CONSTITUTION.md)

本文件定義專案開發的核心準則與不可違反的規範 建立日期: 2026-01-12 當前版本: V9.4


第一章:資料庫與模型層規範

第 1 條:商品 ID 命名規範(絕對禁止違反)

  • 正確: 使用 product.i_code 作為商品唯一識別碼
  • 禁止: 使用 product.momo_id(此屬性不存在)

第 2 條:時間戳處理規範(絕對禁止違反)

  • 正確: 使用 datetime.now(TAIPEI_TZ).replace(tzinfo=None)
  • 禁止: 直接使用 datetime.now() 或保留 tzinfo
  • 理由: SQLite 不支援時區感知的 datetime

第 3 條:價格變動邏輯(絕對禁止違反)

  • 正確: 比對「今日最新價格」與「今日之前的最後一筆價格」
  • 禁止: 僅查詢「昨天 00:00-23:59」的價格記錄

第 4 條:查詢效能優化(強制要求)

  • 正確: 使用批次查詢(如 yesterday_prices_map
  • 禁止: N+1 查詢模式

第二章:爬蟲與資料採集規範

第 5 條:商品圖片 URL 構造(絕對禁止違反)

  • 正確: 使用 CDN 直接構造
    image_url = f"https://m.momoshop.com.tw/moscdn/goods/{i_code}_m.webp"
    
  • 禁止: 使用複雜的 DOM 查詢

第 6 條:爬蟲頻率與禮貌性(強制要求)

  • 正確: 每次請求間隔至少 1 秒
  • 禁止: 高頻率無間隔爬取

第三章API 設計規範

第 8 條API 邏輯一致性(絕對禁止違反)

  • 正確: API 的資料處理邏輯必須與儀表板完全一致
  • 禁止: API 與前端使用不同的計算邏輯

第 9 條API 錯誤處理(強制要求)

  • 正確: 所有 API 必須使用 try-except-finally 結構
  • 正確: 錯誤時返回 JSON 格式: {'products': []}, 500
  • 禁止: 返回 HTML 錯誤頁面或純文字錯誤

第四章:前端 UI/UX 規範

第 11 條:設計系統色彩(絕對禁止違反)

  • 主題色: 紫色漸變 #667eea#764ba2
  • 漲價: 紅色 #dc3545 / #ff6b6b
  • 降價: 綠色 #28a745 / #51cf66

第 12 條:響應式設計(強制要求)

  • 正確: 所有頁面必須支援手機版(< 768px
  • 正確: 使用 Bootstrap 5.3.3

第五章:系統架構規範

第 15 條:服務端口(絕對禁止違反)

  • 正確: Flask 使用 Port 80
  • 禁止: 使用 5888 或其他端口(已廢棄)

第 16 條:資料庫路徑(絕對禁止違反)

  • 正確: data/momo_database.db

第 17 條:時區設定(絕對禁止違反)

  • 正確: 使用 TAIPEI_TZ = pytz.timezone('Asia/Taipei')

第 18 條:日誌系統(強制要求)

  • 正確: 使用 sys_log.info() / sys_log.error() 記錄關鍵操作
  • 禁止: 使用 print() 輸出日誌

第十章:安全性規範

第 31 條:敏感資訊保護(絕對禁止違反)

  • 正確: 所有 API Token、密碼存放於 config.py
  • 禁止: 硬編碼敏感資訊於程式碼中

第 32 條SQL 注入防護(絕對禁止違反)

  • 正確: 使用 SQLAlchemy ORM 的參數化查詢
  • 禁止: 使用字串拼接建構 SQL 查詢

附錄 A常見錯誤與解決方案

錯誤 原因 解決
'Product' object has no attribute 'momo_id' 使用錯誤的屬性名稱 改用 product.i_code
API 返回空資料 價格比對邏輯錯誤(只查昨天) 使用「今日之前最後一筆」邏輯
時間戳比對失敗 時區感知 datetime 與 naive datetime 混用 使用 .replace(tzinfo=None) 統一為 naive

專案憲法 - 擴充版 (PROJECT_CONSTITUTION.md)

版本: 1.3 最後更新: 2026-01-14


第一章:溝通規範

第 1 條:語言使用

  • 所有溝通一律使用繁體中文
  • 包含程式碼註解、文檔說明、Commit 訊息、錯誤訊息、日誌輸出

第二章:安全政策

第 4 條:敏感資訊管理

  • 禁止在程式碼中硬編碼任何敏感資訊
  • 所有憑證、API 金鑰、密碼必須使用環境變數(.env

第 5 條:密碼安全

  • 所有密碼必須使用 pbkdf2:sha256 雜湊儲存
  • 密碼長度至少 8 個字元
  • 登入失敗 5 次後鎖定帳號 5 分鐘

第 7 條CSRF 防護

  • 所有 POST/PUT/DELETE/PATCH 請求必須包含 CSRF token
  • HTML 表單使用: <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
  • AJAX 請求使用: 'X-CSRFToken': getCSRFToken()

第四章:數據爬取規範

第 13 條:爬蟲程式碼穩定性原則

  • 爬蟲程式碼屬於核心業務邏輯,修改時必須格外謹慎
  • 修改前必須備份現有可運作的版本
  • 修改後必須驗證所有爬蟲任務正常執行

第 14 條:爬蟲選擇器維護

  • CSS 選擇器和 XPath 是脆弱的依賴
  • 修改選擇器前必須記錄修改原因
  • 保留舊選擇器作為註解備份

第 15 條:爬蟲錯誤處理

  • 所有爬蟲函數必須包含完整的錯誤處理
  • 必須處理:網路連線失敗、頁面載入超時、元素找不到、資料格式異常、反爬蟲機制觸發

第六章:部署與維運

第 27 條:環境管理規範(2026-04-18 依 ADR-008 改寫)

環境分層:

環境 位置 用途
開發環境 /Users/ooo/Library/Mobile Documents/com~apple~CloudDocs/momo-pro-system/ (macOS,iCloud) 程式碼開發、快速測試
正式環境 /home/ollama/momo-pro/192.168.0.188(Docker Compose) 生產服務、24/7 運行

嚴格禁止:

  • 直接在 188 生產環境隨意改檔案(應走 scp 同步 SOP)
  • 跳過本地測試直接部署到 188
  • .env 或資料庫密碼檔上傳到公開 Git

第 28 條:變更前強制備份原則 ⚠️

核心原則

  • 所有涉及嚴重影響的變更、修改操作,變更前必須先進行完整備份

第 29 條:部署強制規範(2026-04-18 依 ADR-008 改寫)⚠️

核心原則:

  • 188 正式環境為 Docker Compose + volume mount,目前無 Git 版控(本地 Mac 有),CI/CD 方案待定
  • 程式碼變更必先於本地測試,再以 scp(經 110 跳板)同步到 ollama@188:~/momo-pro/
  • 重大結構變更同步記入 ADR + CLAUDE.md 更新記錄

官方唯一部署流程:

  1. 本地 Mac 修改程式碼 + 本地測試通過
  2. 經 110 跳板 scp 到 188:
    scp -o ProxyJump=wooo@192.168.0.110 <檔案> ollama@192.168.0.188:/home/ollama/momo-pro/<目標>
    
  3. 依檔案類型處理:
    • Python 檔案(app.py/services/routes/templates/config.py/database/) → volume mount 即時生效,只需 docker restart momo-pro-system
    • 新增套件 / Dockerfile 變更 → docker compose build momo-app && docker compose up -d momo-app
    • SQL schema 變更 → docker exec -i momo-db psql -U momo -d momo_analytics < migration.sql

禁止行為:

  • 直接在 188 上用 vim 改線上檔案(繞過 scp + 本地審視)
  • docker cp 改容器內檔案(volume mount 下無意義且混亂)
  • 把未測試的 commit scp 上去
  • 在 110 做 kubectl * 類操作(本系統無 K8s)
  • 修改 ~/momo_pro_system/ 於 110(該路徑已空置,不是運行目錄)

唯一例外:

  • 熱修復(Hotfix)若時間緊迫可直接在 188 改,但事後必須把 diff 補回本地並記入 CLAUDE.md 更新記錄

違反後果:

  • 版本混亂(本地與 188 漂移)、無從追蹤
  • 容器重啟後可能丟失(若改了非 mount 的目錄)
  • 未來導入 Git/CI 時衝突

適用範圍

  1. 資料庫結構變更ALTER TABLE, DROP, CREATE
  2. 大量資料修改或刪除(影響 >100 筆)
  3. 系統配置檔案修改
  4. 爬蟲核心邏輯修改
  5. 認證和安全模組修改
  6. 生產環境程式碼更新
  7. K8s ConfigMap 環境變數變更
  8. K8s Deployment YAML 變更
  9. Nginx 配置變更

備份命名規範

資料庫momo_backup_YYYYMMDD_HHMMSS.db
程式碼momo_code_backup_YYYYMMDD_HHMMSS.tar.gz

第 30 條:所有變更必須入 Git 版控(絕對禁止違反)⚠️

核心原則

  • 任何對專案的修改,無論大小,都必須提交到 Git 版本控制
  • 禁止只在伺服器端修改而不同步到 Git

適用範圍

  1. 程式碼變更Python, JavaScript, HTML, CSS
  2. Docker/K8s 配置變更docker-compose.yml, Deployment YAML
  3. n8n 工作流變更n8n-workflows/*.json
  4. Nginx 配置變更
  5. 安全性修復
  6. 環境變數變更ConfigMap
  7. 任何系統配置修改

強制流程

# 1. 本地修改或從伺服器同步變更
# 2. 提交到 Git
git add <changed-files>
git commit -m "描述性訊息"

# 3. 推送到遠端 Git 版控remote 名稱依新 CI/CD 方案而定)
git push <remote> main

Claude 助手責任

  • 每次完成修改任務後,必須主動詢問或執行 Git 提交
  • 若在伺服器端直接修改,必須將變更同步回本地並提交
  • 禁止回覆「已完成」但未提交到 Git 的情況

違反後果

  • 本地與伺服器版本不一致
  • 下次 CI/CD 部署會覆蓋未提交的變更
  • 無法追蹤變更歷史和回滾

第 31 條:端口安全規範(絕對禁止違反)⚠️

2026-01-25 Kali 滲透測試後新增

核心原則

  • 所有內部服務端口必須綁定到 127.0.0.1,禁止暴露到公網 (0.0.0.0)
  • 只有必要的公開服務才能綁定到 0.0.0.0

強制本地綁定的服務

服務 端口 正確配置 風險等級
PostgreSQL 5432 127.0.0.1:5432:5432 🔴 極高
Portainer 9000/9443 127.0.0.1:9000:9000 🔴 極高
Rancher 8880/8443 127.0.0.1:8880:80 🔴 極高
MOMO App 5001 127.0.0.1:5001:80 🟠
Prometheus 9090 127.0.0.1:9090:9090 🟠
Alertmanager 9093 127.0.0.1:9093:9093 🟠
Node Exporter 9100 127.0.0.1:9100:9100 🟡
Postgres Exporter 9187 127.0.0.1:9187:9187 🟡
Loki 3100 127.0.0.1:3100:3100 🟡
cAdvisor 8080 127.0.0.1:8080:8080 🟡

允許公開的服務

  • Port 80/443 (Nginx - HTTPS 反向代理)
  • Port 22 (SSH - 需要密鑰認證)
  • Port 5000 (Registry - 需要認證)

docker-compose.yml 配置範例

# ❌ 錯誤 - 暴露到公網
ports:
  - "5432:5432"

# ✅ 正確 - 僅本地連線
ports:
  - "127.0.0.1:5432:5432"

存取內部服務方式

# SSH Tunnel 存取 Portainer
ssh -L 9000:127.0.0.1:9000 wooo@192.168.0.110
# 然後瀏覽器開啟 http://localhost:9000

第 32 條Nginx 安全配置規範(絕對禁止違反)⚠️

2026-01-25 Kali 滲透測試後新增

核心原則

  • 必須隱藏伺服器版本資訊
  • 必須設定安全 Headers
  • 必須透過 HTTPS 反向代理,禁止直接存取後端服務

強制配置項目

server {
    # 1. 隱藏 Nginx 版本
    server_tokens off;

    # 2. 安全 Headers必須全部加入
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-XSS-Protection "1; mode=block" always;

    # 3. HSTS - 強制 HTTPS防止中間人攻擊
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;

    # 3. 反向代理設定
    location / {
        proxy_pass http://127.0.0.1:5001;  # 後端只綁定本地

        # 4. 隱藏後端版本資訊
        proxy_hide_header X-Powered-By;
        proxy_hide_header Server;
    }
}

Rate Limiting 配置(防止暴力掃描和 DDoS

# 在 nginx.conf 的 http {} 區塊中
limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login:10m rate=3r/s;
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;

# 在 server {} 區塊中
limit_req zone=general burst=20 nodelay;  # 一般請求
limit_conn conn_limit 50;                  # 最大同時連線數

# 登入頁面更嚴格
location /login {
    limit_req zone=login burst=5 nodelay;  # 每秒 3 個請求
}

禁止行為

  • 暴露 Nginx 版本號 (nginx/1.x.x)
  • 暴露後端框架版本 (gunicorn, Python)
  • 允許直接存取後端端口 (5001)
  • 使用 HTTP 傳輸登入憑證
  • 無限制接受請求(易遭 DDoS

驗證指令

# 檢查是否隱藏版本
curl -sI https://mo.wooo.work | grep -i server

# 應該只顯示 "server: nginx" 不帶版本號

第 33 條:資料庫安全規範(絕對禁止違反)⚠️

2026-01-25 Kali 滲透測試後新增

核心原則

  • 資料庫端口絕對禁止暴露到公網
  • 必須使用強密碼
  • 連線必須透過內部網路或 SSH Tunnel

PostgreSQL 安全配置

# docker-compose.yml
postgres:
  ports:
    - "127.0.0.1:5432:5432"  # 僅本地連線
  environment:
    - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}  # 從環境變數讀取

禁止行為

  • 資料庫密碼寫死在程式碼中
  • 使用弱密碼(如 postgres, 123456
  • 允許遠端直接連線資料庫
  • 在錯誤訊息中暴露資料庫結構

第 34 條:容器管理平台安全規範(絕對禁止違反)⚠️

2026-01-25 Kali 滲透測試後新增

核心原則

  • Portainer、Rancher 等容器管理平台屬於最高權限入口
  • 必須限制為本地連線,透過 SSH Tunnel 存取
  • 必須使用強密碼和雙因素認證(如支援)

風險說明

  • 攻擊者一旦獲得容器管理平台存取權,可以:
    • 查看所有容器的環境變數(包含密碼)
    • 執行任意容器命令
    • 部署惡意容器
    • 讀取資料庫內容
    • 完全控制整個系統

強制配置

# Portainer
ports:
  - "127.0.0.1:9000:9000"
  - "127.0.0.1:9443:9443"
# Rancherdocker run 方式)
docker run -d --name rancher \
  -p 127.0.0.1:8880:80 \
  -p 127.0.0.1:8443:443 \
  rancher/rancher:latest

第 35 條SSH 安全規範(絕對禁止違反)⚠️

2026-01-25 Kali 滲透測試後新增

核心原則

  • SSH 服務是伺服器的最重要入口,必須嚴格保護
  • 必須安裝 Fail2Ban 防止暴力破解攻擊
  • 建議使用 SSH Key 認證取代密碼認證

Fail2Ban 強制配置 (/etc/fail2ban/jail.local)

[DEFAULT]
bantime = 3600      # 封鎖 1 小時
findtime = 600      # 10 分鐘內
maxretry = 3        # 最多 3 次失敗
ignoreip = 127.0.0.1/8 192.168.0.0/24  # 白名單

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3

常用指令

# 查看封鎖狀態
sudo fail2ban-client status sshd

# 手動解封 IP
sudo fail2ban-client set sshd unbanip <IP>

# 查看日誌
sudo tail -f /var/log/fail2ban.log

第 36 條:持續性安全監控規範(強制要求)⚠️

2026-01-25 Kali 滲透測試後新增

核心原則

  • 安全不是一次性工作,必須持續監控
  • 所有安全事件必須有日誌和告警機制
  • 定期執行滲透測試,發現新漏洞立即修復

強制監控項目

監控項目 工具 告警方式
SSH 暴力破解 Fail2Ban + Prometheus Exporter Grafana 儀表板
端口掃描偵測 CI/CD Nmap 掃描(待新 CI/CD 方案重建) Telegram 通知
系統資源 Prometheus + Node Exporter Grafana 告警
容器狀態 cAdvisor + Prometheus Grafana 告警
網站可用性 Blackbox Exporter Telegram 通知

Fail2Ban Prometheus Exporter

# 服務位置
/usr/local/bin/fail2ban_exporter.py
systemctl status fail2ban-exporter

# Prometheus 指標
fail2ban_currently_banned{jail="sshd"}
fail2ban_total_banned{jail="sshd"}

每週自動安全掃描(待重建)

# 原本在 GitLab CI 上以排程(每週一 09:00執行 security-scan job
# 掃描nmap -Pn --top-ports 100 192.168.0.110
# 通知Telegram
# GitLab 已撤除,排程掃描需在新 CI/CD 方案或 cron 上重建

發現漏洞處理流程

  1. 立即評估風險等級(極高/高/中/低)
  2. 極高風險1 小時內修復
  3. 高風險24 小時內修復
  4. 中/低風險1 週內修復
  5. 修復後更新憲法和 CLAUDE.md
  6. 提交到 Git 版控

第 37 條:程式碼安全掃描規範(強制要求)⚠️

2026-01-25 新增

核心原則

  • 每次 Push 必須執行自動化程式碼安全掃描
  • 使用 Bandit 工具檢測 Python 常見安全漏洞
  • 高危漏洞必須立即修復後才能部署

掃描工具

工具 用途 說明
Bandit Python 安全掃描 OWASP Top 10、SQL 注入、XSS、密碼硬編碼等

CI/CD Job: security-code-scan(原 GitLab CI Job待新 CI/CD 方案重建)

漏洞嚴重度與處理

嚴重度 圖示 處理方式 通知
高危 (HIGH) 🔴 必須修復後才能合併 Telegram 警告
中危 (MEDIUM) 🟠 應在 24 小時內修復 Telegram 提醒
低危 (LOW) 🟡 可選擇修復 僅記錄

常見檢測項目

  • B101 - assert 在生產環境中使用
  • B105 - 硬編碼密碼
  • B303 - 使用 MD5 或 SHA1
  • B320 - XML 外部實體注入 (XXE)
  • B501 - 禁用 SSL 驗證
  • B608 - SQL 注入

Bandit 報告位置GitLab 已撤除,待新 CI/CD 方案定案後更新路徑)


🔒 資安修復記錄

2026-01-25 Kali Linux 滲透測試修復

漏洞 風險等級 修復方式 狀態
PostgreSQL 5432 暴露公網 🔴 極高 改為 127.0.0.1:5432 已修復
Portainer 9000/9443 暴露公網 🔴 極高 改為 127.0.0.1 已修復
Rancher 8880/8443 暴露公網 🔴 極高 改為 127.0.0.1 已修復
pgAdmin 8088 暴露公網 🔴 極高 改為 127.0.0.1:8088 已修復
MOMO App 5001 暴露公網 🟠 改為 127.0.0.1,透過 Nginx 代理 已修復
Prometheus 9090 暴露公網 🟠 改為 127.0.0.1:9090 已修復
Grafana 3000 暴露公網 🟠 改為 127.0.0.1,透過 mon.wooo.work 已修復
cAdvisor 8080 無認證暴露 🟠 改為 127.0.0.1:8080 已修復
n8n 5678 暴露 API Keys/Sentry 🔴 極高 改為 127.0.0.1:5678 已修復
Registry 5000 HTTP 公開存取 🟠 改為 127.0.0.1:5000透過 HTTPS 已修復
Nginx 暴露版本資訊 🟡 server_tokens off 已修復
後端暴露 Gunicorn/Python 版本 🟡 proxy_hide_header 已修復
缺少安全 Headers 🟡 新增 X-Content-Type-Options 等 已修復
Nextcloud 8081 暴露公網 🟠 改為 127.0.0.1:8081透過 Nginx 代理 已修復
SSH 22 暴力破解風險 🟠 安裝 Fail2Ban (3次失敗封鎖1小時) 已修復
Node Exporter 9100 洩漏硬體資訊 🟡 改為 127.0.0.1:9100 已修復
SSL/TLS 未啟用 HSTS 🟡 新增 Strict-Transport-Security 標頭 已修復
無請求速率限制 (DDoS 風險) 🟡 新增 Rate Limiting (10r/s + burst 20) 已修復

🛡️ 安全監控機制

Fail2Ban 監控 (Prometheus + Grafana)

Exporter 位置: /usr/local/bin/fail2ban_exporter.py 服務: systemctl status fail2ban-exporter 端口: 0.0.0.0:9191 (內部使用)

可用指標:

fail2ban_currently_failed{jail="sshd"}   # 目前失敗嘗試數
fail2ban_total_failed{jail="sshd"}       # 歷史總失敗數
fail2ban_currently_banned{jail="sshd"}   # 目前封鎖 IP 數
fail2ban_total_banned{jail="sshd"}       # 歷史總封鎖數

每週自動安全掃描 (Nmap) — 待新 CI/CD 方案重建

原本建構在 GitLab CI 排程之上(每週一 09:00 執行 security-scan job掃描 PostgreSQL/MySQL/MongoDB/Redis 等常見危險端口並發送 Telegram 通知。GitLab 撤除後此排程掃描已停用,需在新 CI/CD 方案或 cron 上重建。

程式碼安全掃描 (Bandit) — 待新 CI/CD 方案重建

原本建構在 GitLab CI 上(security-code-scan job每次 Push 和手動觸發Bandit 掃描全部 Python 檔案,排除 tests/, venv/, node_modules/;結果依嚴重度發 Telegram 通知。GitLab 撤除後此掃描需在新 CI/CD 方案上重建。

容器映像檔安全掃描 (Trivy) — 待新 CI/CD 方案重建

原本建構在 GitLab CI 上(container-security-scan job每週一排程 + 手動觸發Trivy 掃描 Debian 基礎映像與 Python 套件 CVE僅報告 HIGH/CRITICAL 等級並發送 Telegram 通知。GitLab 撤除後此掃描需在新 CI/CD 方案上重建。


快速檢查清單

新功能開發檢查

  • 程式碼和註解使用繁體中文
  • 無硬編碼敏感資訊
  • 所有輸入經過驗證
  • POST 請求包含 CSRF token
  • 錯誤處理完整
  • 日誌記錄完整

🕷️ 爬蟲修改檢查

  • 備份現有可運作版本
  • 記錄修改原因
  • 保留舊選擇器作為註解
  • 測試新選擇器正確性
  • 驗證資料完整性
  • 更新爬蟲文檔
  • 監控 24 小時確保穩定

開發測試部署流程(2026-04-18 依 ADR-008 改寫)

版本: 3.0 制定日期: 2026-04-18


環境架構

環境 位置 用途 網址
開發環境 /Users/ooo/.../momo-pro-system/ (macOS + iCloud) 本地開發 http://127.0.0.1:5000
正式環境 /home/ollama/momo-pro/ollama@192.168.0.188(Docker Compose) 生產服務 https://mo.wooo.work / https://momo.wooo.work

完整開發部署流程

階段 1:本地開發

cd "/Users/ooo/Library/Mobile Documents/com~apple~CloudDocs/momo-pro-system"
source venv/bin/activate
python app.py

階段 2:本地測試

./run_security_tests.sh  # 若有
# 手動測試主要流程 / UI

階段 3:同步到 188(經 110 跳板)

# 單檔 Python
scp -o ProxyJump=wooo@192.168.0.110 app.py ollama@192.168.0.188:/home/ollama/momo-pro/

# 整個目錄(routes / services / templates 等)
scp -o ProxyJump=wooo@192.168.0.110 -r routes/ ollama@192.168.0.188:/home/ollama/momo-pro/

階段 4:重啟容器(volume mount 後)

ssh -J wooo@192.168.0.110 ollama@192.168.0.188 "docker restart momo-pro-system"

若新增套件或改 Dockerfile:

ssh -J wooo@192.168.0.110 ollama@192.168.0.188 "cd /home/ollama/momo-pro && docker compose build momo-app && docker compose up -d momo-app"

階段 5:驗證部署

# 容器狀態
ssh -J wooo@192.168.0.110 ollama@192.168.0.188 "docker ps --filter name=momo"

# 應用日誌
ssh -J wooo@192.168.0.110 ollama@192.168.0.188 "docker logs -f momo-pro-system --tail 50"

# 對外健康檢查
curl -s https://mo.wooo.work/health
curl -s https://momo.wooo.work/health

常用命令速查

Docker 管理(188)

# 跳板登入
ssh -J wooo@192.168.0.110 ollama@192.168.0.188

# 容器清單
docker ps

# 即時日誌
docker logs -f momo-pro-system --tail 100

# 進入容器
docker exec -it momo-pro-system /bin/bash

# 重啟(volume mount 更新後)
docker restart momo-pro-system

# 重建映像
cd /home/ollama/momo-pro && docker compose build momo-app && docker compose up -d momo-app

回滾流程

方法:以檔案版本回滾(因為是 volume mount,無需 K8s rollout)

# 在本地 Mac 用 git 找回舊版本
git log -- app.py
git show <commit>:app.py > /tmp/app.py.old

# 推回 188
scp -o ProxyJump=wooo@192.168.0.110 /tmp/app.py.old ollama@192.168.0.188:/home/ollama/momo-pro/app.py
ssh -J wooo@192.168.0.110 ollama@192.168.0.188 "docker restart momo-pro-system"

Google Drive API 設定指南 (GOOGLE_DRIVE_SETUP.md)

功能說明

系統會:

  1. 每 30 分鐘自動檢查 Google Drive 指定資料夾
  2. 自動下載 Excel 檔案到本地
  3. 自動匯入資料到資料庫
  4. 自動刪除 Google Drive 上的原始檔案

目前認證狀態

項目
Google Cloud 專案 wooo-481204
OAuth Client ID 132823079326-h9cvj5eahigm8hp9q0b7t5rk77bhu3gp.apps.googleusercontent.com
目前認證帳號 owen.tsai@gmail.com (BA O)
目標資料夾 當日業績匯入
檔案匹配模式 即時業績_當日
匯入後移至 當日業績匯入/已匯入

狀態: Google Drive 自動匯入已正常運作2026-01-24 驗證)


K8s 環境設定(當前使用)

認證檔案位置

K8s Scheduler Pod 使用以下架構掛載 Google 認證:

┌─────────────────────────────────────────────────────────┐
│  K8s Secret: google-drive-credentials                   │
│  ├── google_credentials.json (OAuth 設定)               │
│  └── google_token.pickle (已授權的 Token)               │
└─────────────────────────────────────────────────────────┘
                          │
                          ▼ initContainer 複製到
┌─────────────────────────────────────────────────────────┐
│  emptyDir: /app/config/ (可讀寫)                         │
│  ├── google_credentials.json                            │
│  └── google_token.pickle                                │
└─────────────────────────────────────────────────────────┘

相關 K8s 檔案

  • k8s/08-google-drive-secret.yaml - Google 認證 Secret
  • k8s/05-scheduler.yaml - Scheduler Deployment含 initContainer

更換 Google 帳號步驟

  1. 本地重新認證(取得新的 token.pickle

    cd /Users/ogt/momo-pro-system
    # 刪除舊的 token
    rm -f config/google_token.pickle
    # 重新認證(會開啟瀏覽器)
    python3 -c "
    from services.google_drive_service import drive_service
    drive_service.authenticate()
    "
    
  2. 更新 K8s Secret

    # 將新的 token 編碼為 base64
    CREDENTIALS_B64=$(base64 -i config/google_credentials.json)
    TOKEN_B64=$(base64 -i config/google_token.pickle)
    
    # 更新 k8s/08-google-drive-secret.yaml
    # 將 base64 值更新到 data 區段
    
    # 套用新的 Secret
    kubectl apply -f k8s/08-google-drive-secret.yaml
    
    # 重啟 Scheduler讓 initContainer 重新複製)
    kubectl rollout restart deployment/momo-scheduler -n momo
    
  3. 驗證認證

    kubectl exec -n momo deploy/momo-scheduler -c scheduler -- \
      sh -c 'cd /app && python -c "
    from services.google_drive_service import drive_service
    drive_service.authenticate()
    service = drive_service.service
    about = service.about().get(fields=\"user\").execute()
    print(\"認證帳號:\", about[\"user\"][\"emailAddress\"])
    "'
    

設定步驟摘要(本地/Docker 環境)

1. 建立 Google Cloud 專案

2. 啟用 Google Drive API

  • 前往「API 和服務」→「程式庫」
  • 搜尋並啟用「Google Drive API」

3. 建立 OAuth 2.0 憑證

  • 前往「API 和服務」→「憑證」
  • 建立 OAuth 用戶端 ID桌面應用程式
  • 下載 JSON 並放到 config/google_credentials.json

4. 首次認證

python3 -c "
from services.google_drive_service import drive_service
drive_service.authenticate()
"

5. 設定 Google Drive 資料夾

必須在認證帳號的 Google Drive 建立以下結構:

我的雲端硬碟/
└── 業績報表/
    └── 當日業績/
        └── 即時業績_當日.xlsx  ← 放置要匯入的檔案

常見問題

問題 解決方法
認證失敗,找不到認證檔案 確認 config/google_credentials.json 存在
找不到 Google Drive 資料夾 確認路徑正確(區分大小寫),確認用正確的 Google 帳號
重新授權 刪除 config/google_token.pickle 並重新認證
K8s 認證錯帳號 依照「更換 Google 帳號步驟」重新設定

Docker 部署指南(2026-04-18 依 ADR-008 改寫)

部署架構

本機 (Mac/iCloud)                      188 伺服器 (ollama@192.168.0.188)
┌──────────────────────┐  scp 經110     ┌──────────────────────────────┐
│ 開發環境             │  跳板          │ Docker Compose (V12.0)        │
│ momo-pro-system/     │ ────────────► │  ┌──────────────────────────┐│
│                      │                │  │ momo-pro-system          ││
│ app.py / services/   │                │  │ Gunicorn 4 workers :80   ││
│ routes/ templates/   │                │  │ (host 127.0.0.1:5003)    ││
│ database/ config.py  │                │  └──────────────────────────┘│
└──────────────────────┘                │  momo-db (pgvector/pg14)      │
                                        │  momo-scheduler / openclaw    │
                                        └──────────────────────────────┘

同步檔案到 188

# 單檔
scp -o ProxyJump=wooo@192.168.0.110 app.py ollama@192.168.0.188:/home/ollama/momo-pro/

# 整個目錄
scp -o ProxyJump=wooo@192.168.0.110 -r services ollama@192.168.0.188:/home/ollama/momo-pro/
scp -o ProxyJump=wooo@192.168.0.110 -r routes ollama@192.168.0.188:/home/ollama/momo-pro/
scp -o ProxyJump=wooo@192.168.0.110 -r templates ollama@192.168.0.188:/home/ollama/momo-pro/

重啟 / 重建

# Python 檔案熱更新(最常用)
ssh -J wooo@192.168.0.110 ollama@192.168.0.188 "docker restart momo-pro-system"

# 新套件 / Dockerfile 變更
ssh -J wooo@192.168.0.110 ollama@192.168.0.188 \
  "cd /home/ollama/momo-pro && docker compose build momo-app && docker compose up -d momo-app"

# 完整重啟所有 momo-* 容器
ssh -J wooo@192.168.0.110 ollama@192.168.0.188 \
  "cd /home/ollama/momo-pro && docker compose restart momo-app momo-scheduler"

Volume Mount 檔案清單(這些 host 目錄會即時反映到容器)

ro(唯讀)掛載 — 改完 scp + docker restart 即生效:

  • app.py, scheduler.py, config.py, auth.py
  • services/, routes/, database/, templates/

rw(讀寫)掛載 — 容器與 host 雙向:

  • config/, data/, logs/, backups/

未掛載(修改 host 無效):

  • docs/(CLAUDE.md / ADR 為人工參考,不影響 runtime)
  • static/, web/(編譯進 image,改動需重建)

app.py 重構計畫 (docs/APP_REFACTOR_PLAN.md)

現況分析

  • 總行數: 7,253 行
  • 路由數量: 49 個
  • 函數數量: 約 70 個

最大函數(需優先拆分)

排名 函數名稱 行數 建議模組
1 sales_analysis() 1,020 行 sales_routes.py
2 get_monthly_summary_data() 388 行 monthly_routes.py
3 import_excel() 288 行 import_routes.py
4 get_sales_table_data() 267 行 sales_routes.py
5 edm_dashboard() 244 行 edm_routes.py

目標目錄結構

momo-pro/                    # (188: /home/ollama/momo-pro/)
├── app.py                    # 主應用程式 (精簡後約 500 行)
├── routes/                   # 🆕 路由模組目錄
│   ├── __init__.py          # Blueprint 註冊中心
│   ├── dashboard_routes.py  # 商品看板 (首頁)
│   ├── sales_routes.py      # 業績分析相關
│   ├── daily_sales_routes.py # 當日業績相關
│   ├── monthly_routes.py    # 月結分析相關
│   ├── edm_routes.py        # EDM 儀表板
│   ├── export_routes.py     # 匯出功能
│   ├── import_routes.py     # 匯入功能
│   ├── system_routes.py     # 系統管理
│   └── api_routes.py        # 通用 API
├── services/                 # 服務層
│   ├── cache_service.py     # 🆕 快取服務
│   ├── sales_service.py     # 🆕 業績計算服務
│   └── ...
└── utils/                    # 工具函數
    ├── validators.py        # 🆕 驗證函數
    └── ...

重構執行步驟

順序 模組 複雜度
1 system_routes.py
2 api_routes.py
3 export_routes.py
4 import_routes.py
5 edm_routes.py
6 monthly_routes.py
7 dashboard_routes.py
8 daily_sales_routes.py
9 sales_routes.py

預期效益

指標 重構前 重構後
app.py 行數 7,253 ~500
最大函數行數 1,020 ~200
模組數量 1 10
可測試性

Google Drive 自動匯入功能 (AUTO_IMPORT_README.md)

功能概述

  • 🔄 自動化流程:每 30 分鐘自動檢查 Google Drive
  • 📥 自動下載:發現新檔案立即下載到本地
  • 💾 自動匯入:解析 Excel 並匯入到資料庫
  • 🗑️ 自動清理:匯入完成後刪除 Google Drive 原檔

新增檔案清單

後端服務

  • services/google_drive_service.py - Google Drive API 服務
  • services/import_service.py - 自動匯入服務邏輯
  • database/import_models.py - 匯入任務與配置資料表
  • auto_import_routes.py - API 路由Blueprint

前端介面

  • web/auto_import_index.html - 自動匯入管理頁面

API 端點

端點 方法 說明
/api/import_jobs GET 查詢任務清單
/api/import_jobs/{id} GET 查詢單一任務
/api/import_config GET/POST 取得/設定配置
/api/test_drive_connection POST 測試連接
/api/list_drive_files POST 列出檔案
/api/manual_import POST 手動觸發匯入

資料表結構

import_jobs匯入任務

  • id, job_type, status, drive_file_id, drive_file_name
  • progress_percent, current_step, total_rows, success_rows
  • created_at, started_at, completed_at, error_message

import_config匯入配置

  • config_key, config_value, config_type, description

工作流程

Google Drive 新檔案上傳
        ↓
排程任務執行 (每 30 分鐘)
        ↓
建立匯入任務 (import_jobs)
        ↓
下載到本地 (data/temp/)
        ↓
解析 Excel 並匯入資料庫
        ↓
刪除 Drive 原檔
        ↓
任務完成,更新狀態記錄

故障排除

問題 解決方法
認證失敗 確認 config/google_credentials.json 存在
找不到資料夾 確認路徑正確(區分大小寫)
檔案沒有被刪除 檢查任務狀態是否為「已完成」
匯入失敗 檢查 Excel 格式是否正確

一鍵部署自動化腳本 (2026-01-26 新增)

功能概述

完整的部署自動化系統,支援將 MOMO Pro System 一鍵部署到新的 VM 環境。

支援的部署模式

模式 說明 使用場景
本地部署 在當前主機執行部署 開發/測試環境
SSH 遠端部署 透過 SSH 部署到遠端主機 UAT/正式環境
匯出部署包 生成可攜式 tar.gz 壓縮包 無網路直連環境

檔案結構

deploy/
├── deploy.sh                 # 主入口腳本
├── README.md                 # 部署說明文檔
├── configs/
│   └── .env.template         # 環境變數模板
└── lib/
    ├── common.sh             # 通用函數 (日誌、進度條)
    ├── check.sh              # 環境檢查 (Docker、記憶體、端口)
    ├── config.sh             # 配置生成 (互動式 + 模板)
    ├── docker.sh             # Docker 操作 (構建、啟動、同步)
    ├── database.sh           # 資料庫備份/還原 (完整+CSV)
    ├── ssl.sh                # SSL 憑證 (Let's Encrypt)
    └── health.sh             # 健康檢查 (容器、端點、資料庫)

常用命令

部署

# 本地部署(互動式配置)
./deploy/deploy.sh deploy

# 使用自訂配置部署
./deploy/deploy.sh -e .env.production deploy

# SSH 遠端部署
./deploy/deploy.sh --ssh -h 192.168.1.100 -u root deploy

# 匯出部署包(含資料)
./deploy/deploy.sh --export --with-data

備份與還原

# 完整備份(資料庫 + 配置 + n8n 工作流)
./deploy/deploy.sh backup
# 輸出: backups/momo_backup_20260126_143000.tar.gz

# 從備份還原
./deploy/deploy.sh -b backups/momo_backup_20260126.tar.gz restore

SSL 憑證

# 申請 Let's Encrypt 憑證
./deploy/deploy.sh -d momo.example.com ssl

# 健康檢查
./deploy/deploy.sh health

命令選項

選項 說明
--local 本地部署(預設)
--ssh SSH 遠端部署
--export 匯出部署包
-h, --host SSH 目標主機
-u, --user SSH 用戶名
-p, --path 遠端部署路徑
-e, --env-file 自訂環境變數檔案
-d, --domain 域名SSL 用)
-b, --backup 備份檔案路徑
--no-monitoring 不部署監控服務
--with-data 包含資料庫備份
-y, --yes 跳過確認提示

資料庫備份特點

  • 完整 SQL 備份: 結構 + 資料 (pg_dump)
  • CSV 分表匯出: 每個資料表獨立 CSV 檔案,方便檢視
  • 備份摘要報告: 資料表行數、大小統計
  • 自動壓縮: 生成 .tar.gz 壓縮包

備份內容

backups/momo_backup_20260126_143000/
├── database/
│   ├── postgres_full_20260126_143000.sql   # 完整 SQL
│   ├── backup_summary.txt                   # 備份摘要
│   └── tables/
│       ├── users.csv
│       ├── products.csv
│       ├── daily_sales_snapshot.csv
│       └── ...                              # 所有資料表
├── configs/
│   ├── .env
│   ├── docker-compose.yml
│   └── config/
└── n8n/
    └── *.json                               # 所有工作流程

環境需求

硬體需求

項目 最低需求 建議配置
CPU 4 核心 8 核心
RAM 8 GB 16 GB
硬碟 50 GB SSD 100 GB SSD

端口需求

端口 服務 必要
5001 Flask App
5432 PostgreSQL
80/443 Nginx
3000 Grafana 選填
9090 Prometheus 選填
5678 n8n 選填

PostgreSQL 慢查詢監控 (2026-01-26 新增)

功能概述

新增 PostgreSQL 慢查詢監控 API 及 n8n 自動修復工作流程。

API 端點

端點 方法 說明
/api/system/db/slow_queries GET 取得慢查詢列表
/api/system/db/optimize POST 執行 VACUUM ANALYZE
/api/system/db/stats GET 資料庫統計資訊
/api/system/monitor/overview GET 監控總覽(整合所有狀態)

n8n 工作流程

名稱: PostgreSQL 慢查詢監控 (含自動修復) 檔案: n8n-workflows/13-slow-query-monitor.json

工作流程:

  1. 每 15 分鐘執行
  2. 呼叫 /api/system/db/slow_queries 取得慢查詢
  3. 分析是否需要優化≥3 個慢查詢或重複模式)
  4. 發送 Telegram 告警
  5. 自動執行 VACUUM ANALYZE如需要
  6. 通知優化結果

慢查詢檢測邏輯

// 閾值設定
const threshold = 5; // 秒

// 觸發優化條件
if (slowQueries.length >= 3) {
    needsOptimize = true;
}

// 重複慢查詢檢測(可能需要索引)
if (repeatedSlowQueries.length > 0) {
    needsOptimize = true;
}

Monitor 頁面更新

檔案: docker/nginx/html/monitor-index.html

新增功能:

  • 即時服務狀態面板Registry、Grafana、Prometheus、n8n、MOMO App、Database
  • Prometheus 告警顯示面板
  • n8n 工作流程狀態面板
  • 每 30 秒自動刷新

n8n 監控工作流程清單

檔案 名稱 排程 功能
11-registry-health-monitor.json Registry 健康監控 每 10 分鐘 Docker Registry 健康檢查
12-google-drive-import-monitor.json Google Drive 匯入監控 每 30 分鐘 自動匯入失敗告警
13-slow-query-monitor.json PostgreSQL 慢查詢監控 每 15 分鐘 慢查詢告警 + 自動 VACUUM

CI/CD 與一鍵部署自動化 (2026-02-06 新增)

概述

完整的部署自動化系統,包含:

  • CI/CD 流程: GitLab 已撤除,新方案待定
  • 環境自動安裝: 在全新主機上自動安裝所有必要套件
  • 一鍵完整部署: 環境安裝 + 應用部署一次完成

CI/CD 流程(待定)

2026-04-18 備註: 原 GitLab CI/CD.gitlab-ci.yml.gitlab-ci-simple.yml)已隨 GitLab 撤除而退役。下列 Pipeline 骨架保留作為新 CI/CD 方案的參考需求。

預期階段骨架

git push main (remote 待定)
    │
    ▼
╔═══════════════════════════════════════╗
║  CI/CD Pipeline (待新方案定案)         ║
╠═══════════════════════════════════════╣
║  Stage: test                          ║
║  • pytest 測試 (允許失敗)              ║
╠═══════════════════════════════════════╣
║  Stage: deploy                        ║
║  • rsync 同步程式碼到 K3s 主機         ║
║  • docker build (在 K3s 主機建置)      ║
║  • k3s ctr images import (匯入映像)   ║
║  • kubectl rollout restart (重啟)     ║
║  • 健康檢查                           ║
║  • Telegram 通知                      ║
╚═══════════════════════════════════════╝

關鍵特點(設計需求)

特點 說明
不依賴 Registry 本地建置 + K3s containerd 直接匯入(可選)
自動健康檢查 部署後自動驗證服務狀態
Telegram 通知 部署成功/失敗即時通知
自動回滾 部署失敗可快速回滾

相關檔案

檔案 說明
scripts/deploy/build-and-deploy.sh 快速部署腳本(手動執行)
scripts/verify-cicd.sh CI/CD 驗證腳本(原 GitLab CI 用,待改寫)

一鍵部署到新主機

完整部署命令

# 1. 複製專案到新主機
scp -r momo-pro-system root@新主機IP:/opt/

# 2. SSH 到新主機執行完整部署
ssh root@新主機IP
cd /opt/momo-pro-system
sudo ./deploy/scripts/full-deploy.sh --domain mo.example.com --ssl

一個命令完成:環境安裝 + K8s 部署 + Nginx + SSL + 監控 + 自動啟動

部署流程

執行 full-deploy.sh
        │
        ▼
Phase 1: 環境安裝 ─────────────────────────────────────────────
        • 檢測 OS (Ubuntu/Debian)
        • 安裝基礎套件 (curl, git, vim, htop, jq...)
        • 安裝 Docker + Docker Compose
        • 安裝 K3s + Helm
        • 安裝 Nginx + 安全配置
        • 安裝 Certbot (Let's Encrypt)
        • 設定 UFW 防火牆
        • 設定 Fail2Ban
        • 系統優化 (核心參數、檔案限制)
        │
        ▼
Phase 2: K8s 配置 ─────────────────────────────────────────────
        • 建立 momo namespace
        • 部署 Secrets + ConfigMap
        • 部署 PostgreSQL StatefulSet
        • 部署 momo-app Deployment
        • 部署 momo-scheduler Deployment
        │
        ▼
Phase 3: 映像建置 ─────────────────────────────────────────────
        • docker build -t momo-pro-system:local
        • docker save | k3s ctr images import
        • kubectl rollout restart
        │
        ▼
Phase 4-5: 網路配置 ───────────────────────────────────────────
        • Nginx 反向代理配置
        • Let's Encrypt SSL 證書
        │
        ▼
Phase 6: 監控系統 ─────────────────────────────────────────────
        • Prometheus + Grafana (Helm)
        • Alertmanager 告警
        │
        ▼
Phase 7-8: 自動化 ─────────────────────────────────────────────
        • systemd 開機自動啟動
        • 健康檢查
        • Telegram 通知

自動安裝的套件清單

基礎套件

套件 用途
curl, wget 檔案下載
git 版本控制
vim, htop, iotop 編輯器與系統監控
jq JSON 處理
rsync 檔案同步
unzip, tar, gzip 壓縮解壓縮
net-tools, dnsutils 網路工具
build-essential 編譯工具
cron, logrotate 排程與日誌管理

容器與 Kubernetes

套件 版本 用途
Docker CE 最新 容器運行環境
Docker Compose Plugin 多容器編排
K3s 最新 輕量級 Kubernetes
Helm v3 K8s 套件管理

Python

套件 用途
python3 Python 執行環境
pip Python 套件管理
venv 虛擬環境

Web 伺服器與 SSL

套件 用途
Nginx 反向代理 + 負載均衡
Certbot Let's Encrypt SSL 自動證書

安全

套件 用途
Fail2Ban 防暴力破解 (SSH 3次失敗封鎖1小時)
UFW 防火牆

監控

套件 用途
Node Exporter 主機指標收集
Prometheus 指標儲存與查詢 (Helm)
Grafana 監控儀表板 (Helm)

資料庫

套件 用途
postgresql-client PostgreSQL 客戶端工具

部署腳本說明

1. 環境安裝腳本

檔案: deploy/scripts/setup-environment.sh

只安裝環境,不部署應用:

sudo ./deploy/scripts/setup-environment.sh [選項]

選項:
    --user <name>       部署用戶(預設: wooo
    --domain <domain>   域名
    --no-docker         不安裝 Docker
    --no-k3s            不安裝 K3s
    --no-nginx          不安裝 Nginx
    --no-certbot        不安裝 Certbot
    --no-monitoring     不安裝監控工具
    --no-firewall       不設定防火牆

2. 完整部署腳本

檔案: deploy/scripts/full-deploy.sh

環境安裝 + 應用部署:

sudo ./deploy/scripts/full-deploy.sh [選項]

選項:
    --user <name>       部署用戶(預設: wooo
    --domain <domain>   域名
    --ssl               設定 SSL 證書
    --skip-env          跳過環境安裝(環境已準備好時使用)

3. 快速部署腳本

檔案: scripts/deploy/build-and-deploy.sh

日常更新用(環境已準備好):

./scripts/deploy/build-and-deploy.sh

# 功能:
# 1. 本地 Docker 建置
# 2. 映像傳輸到 K3s 主機
# 3. 匯入 K3s containerd
# 4. 重啟服務
# 5. 健康檢查
# 6. Telegram 通知

4. CI/CD 驗證腳本

檔案: scripts/verify-cicd.sh

驗證 CI/CD 流程完整性:

./scripts/verify-cicd.sh

# 驗證項目:
# 1. 本地環境 (Docker, Git, SSH)
# 2. SSH 連線 (K3s 主機)
# 3. K8s 服務狀態
# 4. 應用健康檢查
# 5. CI/CD 檔案完整性
# 6. 自動啟動設定
# 7. 端對端部署測試
# 8. 監控系統

日常更新流程

環境已安裝後,日常更新只需:

# 方法 1: 使用快速部署腳本
./scripts/deploy/build-and-deploy.sh

# 方法 2: 手動步驟
docker build -t momo-pro-system:local .
docker save momo-pro-system:local | sudo k3s ctr images import -
kubectl rollout restart deployment/momo-app deployment/momo-scheduler -n momo

系統需求

硬體需求

項目 最低需求 建議配置
CPU 2 核心 4+ 核心
RAM 4 GB 8+ GB
硬碟 30 GB 50+ GB SSD

支援的作業系統

OS 版本 狀態
Ubuntu 22.04, 24.04 完全支援
Debian 11, 12 完全支援

防火牆規則 (自動設定)

端口 服務 存取範圍
22 SSH 公開
80 HTTP 公開
443 HTTPS 公開
6443 K3s API 僅內網

部署檔案清單

deploy/
├── deploy.sh                    # 進階部署主腳本
├── README.md                    # 部署說明文檔
├── QUICK_START.md               # 快速部署指南
├── configs/
│   └── .env.template            # 環境變數模板
├── lib/
│   ├── common.sh                # 通用函數
│   ├── check.sh                 # 環境檢查
│   ├── config.sh                # 配置生成
│   ├── docker.sh                # Docker 操作
│   ├── database.sh              # 資料庫備份還原
│   ├── ssl.sh                   # SSL 憑證
│   ├── health.sh                # 健康檢查
│   ├── k8s.sh                   # K8s 管理
│   ├── monitoring.sh            # 監控部署
│   ├── systemd.sh               # Systemd 服務
│   └── registry.sh              # Registry 管理
└── scripts/
    ├── setup-environment.sh     # 🆕 環境自動安裝
    ├── full-deploy.sh           # 🆕 完整一鍵部署
    └── setup-firewall.sh        # 防火牆設定

scripts/
├── deploy/
│   └── build-and-deploy.sh      # 快速部署腳本
├── verify-cicd.sh               # 🆕 CI/CD 驗證腳本
└── tools/
    ├── system_startup_complete.sh  # 系統啟動腳本
    └── momo-startup-complete.service # systemd 服務

🚀 WOOO AIOps - 智能運維 SaaS 產品 (2026-02-13 新增)

產品概覽

WOOO AIOps 是基於 MOMO Pro System 監控與自動修復經驗打造的 SaaS 產品, 讓新網站能夠即時接入監控、告警、自動修復與一鍵部署功能。

項目 說明
產品名稱 WOOO AIOps (AI Operations Platform)
目標客戶 需要快速建立監控的中小型網站
核心價值 10 分鐘內完成監控 + 自動修復配置
技術棧 FastAPI + React/Next.js + K8s + Prometheus

產品特點

功能 說明
一鍵部署 支援 FastAPI、Flask、Express、Next.js 等主流框架
智能監控 自動整合 Prometheus + Grafana
AI 告警 基於歷史資料的智能告警
自動修復 重啟、擴容、回滾、記憶體調整等 8 種修復策略
多租戶 完整的用戶隔離與計費系統

架構圖

┌─────────────────────────────────────────────────────────────────────────────┐
│                          WOOO AIOps Platform                                │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  Web Portal (React/Next.js)                                                 │
│  ├── Dashboard          # 總覽儀表板                                        │
│  ├── Apps Management    # 應用管理                                          │
│  ├── Monitoring         # 監控中心                                          │
│  ├── Repairs History    # 修復記錄                                          │
│  └── Settings           # 系統設定                                          │
│                                                                             │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │                         FastAPI Backend                              │   │
│  │  /api/auth/*      # 認證 (JWT)                                       │   │
│  │  /api/apps/*      # 應用 CRUD                                        │   │
│  │  /api/deployments/* # 部署管理                                       │   │
│  │  /api/monitoring/*  # 監控資料                                       │   │
│  │  /api/repairs/*     # 修復記錄                                       │   │
│  │  /api/users/*       # 用戶管理                                       │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
│                                                                             │
│  ┌───────────────┐  ┌───────────────┐  ┌───────────────┐                  │
│  │ Deploy Engine │  │ Monitor Engine│  │ Repair Engine │                  │
│  │               │  │               │  │               │                  │
│  │ • Template    │  │ • Prometheus  │  │ • 8 種策略   │                  │
│  │   Renderer    │  │   Client      │  │ • 自動觸發   │                  │
│  │ • K8s Client  │  │ • Alertmanager│  │ • 執行追蹤   │                  │
│  └───────────────┘  └───────────────┘  └───────────────┘                  │
│                                                                             │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │                        Kubernetes Cluster                            │   │
│  │                                                                       │   │
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐                   │   │
│  │  │ User App A  │  │ User App B  │  │ User App C  │                   │   │
│  │  │ (FastAPI)   │  │ (Next.js)   │  │ (Express)   │                   │   │
│  │  └─────────────┘  └─────────────┘  └─────────────┘                   │   │
│  │                                                                       │   │
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐                   │   │
│  │  │ Prometheus  │  │   Grafana   │  │Alertmanager │                   │   │
│  │  └─────────────┘  └─────────────┘  └─────────────┘                   │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

目錄結構

aiops-core/
├── README.md                    # 產品說明文檔
├── requirements.txt             # Python 依賴
│
├── api/                         # FastAPI 後端
│   ├── main.py                  # FastAPI 入口
│   └── routers/
│       ├── auth.py              # JWT 認證
│       ├── apps.py              # 應用 CRUD
│       ├── deployments.py       # 部署管理
│       ├── monitoring.py        # 監控 API
│       ├── repairs.py           # 修復記錄
│       └── users.py             # 用戶管理
│
├── database/                    # 資料庫層
│   ├── models.py                # SQLAlchemy 模型
│   └── session.py               # 資料庫連線
│
├── deploy_engine/               # 部署引擎
│   ├── deploy_service.py        # 部署服務
│   ├── template_renderer.py     # Jinja2 模板渲染
│   └── k8s_client.py            # kubectl 封裝
│
├── monitor_engine/              # 監控引擎
│   ├── monitor_service.py       # 監控服務
│   ├── prometheus_client.py     # Prometheus API
│   └── alert_manager.py         # Alertmanager API
│
├── repair_engine/               # 修復引擎
│   ├── repair_service.py        # 修復服務
│   ├── repair_executor.py       # 修復執行器
│   └── repair_strategies.py     # 修復策略
│
├── templates/                   # K8s 模板 (Jinja2)
│   ├── base/
│   │   ├── namespace.yaml.j2
│   │   ├── service.yaml.j2
│   │   └── ingress.yaml.j2
│   └── frameworks/
│       ├── fastapi/deployment.yaml.j2
│       ├── flask/deployment.yaml.j2
│       ├── express/deployment.yaml.j2
│       └── nextjs/deployment.yaml.j2
│
└── web/                         # React/Next.js 前端
    ├── package.json
    ├── tailwind.config.js
    └── src/
        ├── lib/api.ts           # API 客戶端
        └── pages/
            ├── index.tsx        # Dashboard
            ├── monitoring.tsx   # 監控中心
            ├── repairs.tsx      # 修復記錄
            └── apps/
                ├── index.tsx    # 應用列表
                └── new.tsx      # 創建應用精靈

資料庫模型

核心表

表名 說明 主要欄位
users 用戶帳號 id, email, password_hash, plan, company
apps 應用配置 id, user_id, name, framework, status, domain
deployments 部署記錄 id, app_id, version, status, started_at
alerts 告警記錄 id, app_id, name, severity, status
repairs 修復記錄 id, app_id, action, status, attempt
api_keys API 金鑰 id, user_id, key_hash, scopes

列舉類型

class PlanType(str, Enum):
    FREE = "free"           # 最多 2 個應用
    STARTER = "starter"     # 最多 5 個應用
    PRO = "pro"             # 最多 20 個應用
    ENTERPRISE = "enterprise"  # 無限制

class Framework(str, Enum):
    FASTAPI = "fastapi"
    FLASK = "flask"
    EXPRESS = "express"
    NEXTJS = "nextjs"
    DJANGO = "django"
    NESTJS = "nestjs"

class AppStatus(str, Enum):
    PENDING = "pending"
    DEPLOYING = "deploying"
    RUNNING = "running"
    STOPPED = "stopped"
    ERROR = "error"

class RepairAction(str, Enum):
    RESTART = "restart"
    SCALE_UP = "scale_up"
    SCALE_DOWN = "scale_down"
    ROLLBACK = "rollback"
    INCREASE_MEMORY = "increase_memory"
    INCREASE_CPU = "increase_cpu"
    VACUUM_DB = "vacuum_db"
    CLEAR_CACHE = "clear_cache"

API 端點

認證 API

端點 方法 說明
/api/auth/login POST 登入取得 JWT
/api/auth/register POST 註冊新用戶
/api/auth/refresh POST 刷新 Token
/api/auth/me GET 取得當前用戶

應用 API

端點 方法 說明
/api/apps GET 列出所有應用
/api/apps POST 創建新應用
/api/apps/{id} GET 取得應用詳情
/api/apps/{id} PUT 更新應用
/api/apps/{id} DELETE 刪除應用
/api/apps/{id}/start POST 啟動應用
/api/apps/{id}/stop POST 停止應用
/api/apps/{id}/restart POST 重啟應用

部署 API

端點 方法 說明
/api/deployments GET 列出部署記錄
/api/deployments POST 觸發新部署
/api/deployments/{id} GET 部署詳情
/api/deployments/{id}/cancel POST 取消部署
/api/deployments/{id}/rollback POST 回滾到此版本

監控 API

端點 方法 說明
/api/monitoring/dashboard GET 總覽資料
/api/monitoring/apps/{id}/metrics GET 應用指標
/api/monitoring/apps/{id}/health GET 健康狀態
/api/monitoring/alerts GET 告警列表

修復 API

端點 方法 說明
/api/repairs GET 修復記錄列表
/api/repairs/stats GET 修復統計
/api/repairs/apps/{id}/trigger POST 手動觸發修復

自動修復策略

告警到修復動作映射

告警類型 修復動作 說明
HighCpuUsage scale_up CPU > 80%,自動擴容
HighMemoryUsage increase_memory 記憶體 > 85%,增加限制
PodCrashLoopBackOff restart Pod 崩潰,嘗試重啟
HighErrorRate rollback 錯誤率 > 5%,回滾版本
PodOOMKilled increase_memory OOM增加 50% 記憶體
HighResponseTime scale_up P95 > 2s擴容
DatabaseHighConnections vacuum_db 連線 > 80%,執行 VACUUM
DatabaseDeadlock kill_query 發現死鎖,終止查詢

修復執行流程

告警觸發
    │
    ▼
repair_service.process_alert()
    │
    ├─ 檢查是否符合自動修復條件
    │
    ├─ 建立 Repair 記錄
    │
    ├─ repair_executor.execute()
    │   ├─ restart: kubectl rollout restart
    │   ├─ scale_up: kubectl scale --replicas +1
    │   ├─ rollback: kubectl rollout undo
    │   ├─ increase_memory: kubectl patch +50%
    │   ├─ vacuum_db: VACUUM ANALYZE
    │   └─ kill_query: pg_terminate_backend()
    │
    └─ 更新修復狀態 + 發送通知

支援的框架

Python 框架

框架 版本 預設配置
FastAPI 0.100+ Gunicorn + Uvicorn, Port 8000
Flask 2.0+ Gunicorn, Port 5000
Django 4.0+ Gunicorn, Port 8000

JavaScript 框架

框架 版本 預設配置
Express 4.18+ Node.js, Port 3000
Next.js 14+ Node.js, Port 3000
NestJS 10+ Node.js, Port 3000

K8s 模板變數

變數 說明 範例
app.name 應用名稱 my-api
app.namespace K8s 命名空間 user-123-my-api
app.framework 框架類型 fastapi
app.replicas 副本數 2
app.port 容器端口 8000
app.domain 自訂域名 api.example.com
resources.cpu_request CPU 請求 100m
resources.memory_request 記憶體請求 256Mi

運行方式

後端 (FastAPI)

cd aiops-core

# 安裝依賴
pip install -r requirements.txt

# 設定環境變數
export DATABASE_URL="postgresql://user:pass@localhost/aiops"
export JWT_SECRET="your-secret-key"
export PROMETHEUS_URL="http://prometheus:9090"
export ALERTMANAGER_URL="http://alertmanager:9093"

# 啟動服務
uvicorn api.main:app --host 0.0.0.0 --port 8000 --reload

前端 (Next.js)

cd aiops-core/web

# 安裝依賴
npm install

# 設定環境變數
echo 'NEXT_PUBLIC_API_URL=http://localhost:8000/api' > .env.local

# 開發模式
npm run dev

# 生產建置
npm run build
npm start

開發狀態

已完成

模組 檔案數 狀態
Deploy Engine 4 完成
Monitor Engine 4 完成
Repair Engine 4 完成
FastAPI Backend 8 完成
Database Models 3 完成
K8s Templates 7 完成
Web Portal 8 完成
總計 38

待開發

功能 優先級 說明
計費系統整合 Stripe/金流整合
多租戶隔離 K8s namespace 隔離
自訂告警規則 用戶自定義閾值
Slack/Discord 通知 多渠道告警
日誌聚合 Loki 整合
效能分析 APM 功能

更新記錄

  • 2026-02-13:

    • 🆕 新增 WOOO AIOps 產品核心模組 (38 個檔案)
    • 🆕 Deploy Engine: 支援 4 種框架的 K8s 部署
    • 🆕 Monitor Engine: Prometheus + Grafana + Alertmanager 整合
    • 🆕 Repair Engine: 8 種自動修復策略
    • 🆕 FastAPI Backend: 6 個 API 路由模組
    • 🆕 Web Portal: Dashboard、應用管理、監控、修復記錄頁面
    • 🆕 Database Models: User、App、Deployment、Alert、Repair
  • 2026-02-06:

    • 新增 CI/CD 完整驗證腳本 (scripts/verify-cicd.sh)
    • 新增環境自動安裝腳本 (deploy/scripts/setup-environment.sh)
    • 新增完整一鍵部署腳本 (deploy/scripts/full-deploy.sh)
    • 新增快速部署腳本 (scripts/deploy/build-and-deploy.sh)
    • K8s 優化配置 (k8s/optimized/)
    • 完整 K8s 配置檔案 (k8s/00-namespace.yaml, k8s/01-secrets.yaml, k8s/03-postgres.yaml)
    • 系統自動啟動機制 (systemd)
    • 完整部署文檔更新
  • 2026-01-26:

    • 新增一鍵部署自動化腳本系統
    • 新增 PostgreSQL 慢查詢監控 API
    • 新增 n8n 慢查詢自動修復工作流程
    • 更新 Monitor 頁面整合所有監控狀態

⚖️ 第十三章AI 架構完整憲法2026-04-18 加入 + 統帥批准)

第 40 條AI 學習數據雙寫規範(絕對禁止違反)

  • 正確:所有 AI 產出PPT 洞察、競品分析、對話記錄)必須雙寫 PostgreSQL ai_insights + pgvector embedding
  • 禁止:只寫 DB 不寫 KMRAG 無法語意搜尋)
  • 禁止:只寫 KM 不寫 DB精確 period/sku 查詢無法命中)
  • 理由DB 是精準命中KM 是語意搜尋兩者互補缺一不可ADR-007
  • 實作NemoTron store_insight tool call 觸發雙寫Hermes 非同步補 embedding

第 41 條:架構決策 ADR 規範(強制要求)

  • 正確:任何重大架構決策(引入新依賴、改資料庫 schema、改 AI 路由邏輯)必須建立 docs/adr/ADR-XXX-*.md
  • 正確ADR 建立後同步更新 docs/adr/README.md 索引 + 相關 SOT + Memory
  • 禁止:口頭決策不留文字記錄
  • 格式Context → Decision → Alternatives Considered → Consequences
  • 目錄docs/adr/2026-04-18 已建立 ADR-001 ~ ADR-007

第 42 條Memory 跨 Session 持久化規範(強制要求)

  • 正確:重大協作 context、統帥偏好、技術決策必須寫入 Memory 目錄
  • 目錄~/.claude/projects/.../memory/
  • 索引MEMORY.md 必須保持最新索引
  • 禁止:依賴 Claude 對話 session 記憶(必有 context window 截斷問題)
  • 類型分類user(統帥偏好)、feedback(決策回饋)、project(專案技術)、reference(地圖參考)

第 43 條Embedding 必須本地化到 Hermes強制要求

  • 正確:使用 bge-m3(或 nomic-embed-text)掛載在 192.168.0.111 Ollama
  • 禁止:呼叫外部 Embedding API成本 + 數據隱私雙重問題)
  • 維度vector(1024)ADR-003
  • 理由統帥明確要求「Hermes 機器徹底包辦所有苦力運算,把數據隱私與成本降到絕對的零」

第 44 條NemoTron 配額耗盡 Fallback 鏈(強制要求)

  • 正確nemoton_dispatcher_service.py 必須有 try-exceptHTTP 429 → 立刻切換 _hermes_rule_fallback()
  • 禁止:配額耗盡時讓告警管線中斷(雙 11 等節慶高峰時風險最高)
  • 標記:降級模式告警需帶 🟡 前綴讓統帥識別ADR-004

第 45 條KM 品質分數時間衰減(強制要求)

  • 公式effective_score = base_score × e^(-decay_rate × days_passed)
  • 預設 decay_rate0.005decay_exempt=True 用於結構性/憲法類知識
  • 理由:確保 RAG 優先抓取最新適用洞察避免歷史偏誤ADR-005

📌 遊戲規則全文見第零章(文件最頂部)。本章條款是第零章的 AI 專項細化。

🏷️ 專案正名記錄

  • 2026-04-18:正式更名為 EwoooCADR-006
  • Docker image tag 維持 momo-pro-system(延後處理)
  • Domain 維持 mo.wooo.workmomo.wooo.work(皆指向 UAT)