Some checks failed
CD Pipeline / deploy (push) Failing after 59s
- 建立 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>
359 lines
8.0 KiB
Markdown
359 lines
8.0 KiB
Markdown
# MOMO Pro System - 技術架構
|
||
|
||
> 最後更新:2026-01-29
|
||
|
||
---
|
||
|
||
## 🏗️ 整體架構
|
||
|
||
```mermaid
|
||
graph TB
|
||
subgraph "用戶端"
|
||
Browser[🌐 瀏覽器]
|
||
Telegram[📱 Telegram Bot]
|
||
LINE[📱 LINE Bot]
|
||
end
|
||
|
||
subgraph "入口層"
|
||
Nginx[🔒 Nginx<br/>SSL + 反向代理]
|
||
end
|
||
|
||
subgraph "應用層 (K8s)"
|
||
Flask[🐍 Flask App]
|
||
Scheduler[⏰ 排程器]
|
||
end
|
||
|
||
subgraph "AI 服務"
|
||
Ollama[🦙 Ollama<br/>llama3:70b]
|
||
Gemini[✨ Gemini API]
|
||
end
|
||
|
||
subgraph "資料層"
|
||
PostgreSQL[(🐘 PostgreSQL)]
|
||
Redis[(📦 Redis Cache)]
|
||
end
|
||
|
||
subgraph "外部服務"
|
||
GDrive[📁 Google Drive]
|
||
SMTP[📧 SMTP Server]
|
||
MOMO[🛒 MOMO 電商]
|
||
end
|
||
|
||
subgraph "監控層"
|
||
Prometheus[📊 Prometheus]
|
||
Grafana[📈 Grafana]
|
||
Alertmanager[🚨 Alertmanager]
|
||
end
|
||
|
||
Browser --> Nginx
|
||
Telegram --> Flask
|
||
LINE --> Flask
|
||
Nginx --> Flask
|
||
Flask --> PostgreSQL
|
||
Flask --> Redis
|
||
Flask --> Ollama
|
||
Flask --> Gemini
|
||
Flask --> GDrive
|
||
Flask --> SMTP
|
||
Scheduler --> MOMO
|
||
Scheduler --> PostgreSQL
|
||
Flask --> Prometheus
|
||
Prometheus --> Grafana
|
||
Prometheus --> Alertmanager
|
||
```
|
||
|
||
---
|
||
|
||
## 📚 技術棧總覽
|
||
|
||
| 層級 | 技術 | 版本 | 用途 |
|
||
|------|------|------|------|
|
||
| **後端框架** | Flask | 2.3+ | Web 應用框架 |
|
||
| **ORM** | SQLAlchemy | 2.0+ | 資料庫物件映射 |
|
||
| **資料庫** | PostgreSQL | 15 | 主資料庫 (生產環境) |
|
||
| **資料庫** | SQLite | 3 | 開發/本地環境 |
|
||
| **快取** | Redis | 7.0 | Session + 資料快取 |
|
||
| **前端框架** | Bootstrap | 5.3 | UI 元件庫 |
|
||
| **圖表** | Chart.js | 4.0 | 資料視覺化 |
|
||
| **模板引擎** | Jinja2 | 3.1 | HTML 模板渲染 |
|
||
| **容器** | Docker | 24.0 | 容器化部署 |
|
||
| **編排** | K3s | 1.34 | Kubernetes 輕量版 |
|
||
| **CI/CD** | GitLab CI | - | 持續整合部署 |
|
||
| **Registry** | Harbor | 2.10 | 容器映像倉庫 |
|
||
| **監控** | Prometheus | 2.51 | 指標收集 |
|
||
| **視覺化** | Grafana | 10.0 | 監控儀表板 |
|
||
| **日誌** | Loki | 2.9 | 日誌聚合 |
|
||
| **AI (本地)** | Ollama | 0.1+ | LLM 推理引擎 |
|
||
| **AI (雲端)** | Gemini | 1.5/2.5 | Google AI API |
|
||
| **自動化** | n8n | 1.30 | 低代碼工作流 |
|
||
| **爬蟲** | Selenium | 4.18 | 網頁自動化 |
|
||
| **爬蟲** | BeautifulSoup | 4.12 | HTML 解析 |
|
||
|
||
---
|
||
|
||
## 🐍 後端架構
|
||
|
||
### Flask 應用結構
|
||
|
||
```
|
||
Flask App
|
||
├── Blueprints (路由模組)
|
||
│ ├── dashboard_routes # 商品看板
|
||
│ ├── daily_sales_routes # 每日業績
|
||
│ ├── ai_routes # AI 文案
|
||
│ ├── user_routes # 用戶管理
|
||
│ └── ... # 17 個路由模組
|
||
│
|
||
├── Services (業務邏輯)
|
||
│ ├── AI Services # Ollama + Gemini
|
||
│ ├── Crawler Services # 爬蟲服務
|
||
│ ├── Notification # 通知服務
|
||
│ └── ... # 27 個服務模組
|
||
│
|
||
└── Database (資料層)
|
||
├── SQLAlchemy Models # ORM 模型
|
||
└── Database Manager # 連線管理
|
||
```
|
||
|
||
### 關鍵依賴 (requirements.txt)
|
||
|
||
```txt
|
||
Flask>=2.3.0
|
||
SQLAlchemy>=2.0.0
|
||
gunicorn>=21.0.0
|
||
psycopg2-binary>=2.9.0
|
||
selenium>=4.18.0
|
||
beautifulsoup4>=4.12.0
|
||
openpyxl>=3.1.0
|
||
google-api-python-client>=2.0.0
|
||
python-telegram-bot>=20.0
|
||
requests>=2.31.0
|
||
Pillow>=10.0.0
|
||
```
|
||
|
||
---
|
||
|
||
## 🎨 前端架構
|
||
|
||
### 技術選型
|
||
|
||
| 項目 | 技術 | 說明 |
|
||
|------|------|------|
|
||
| **CSS 框架** | Bootstrap 5.3 | 響應式 UI 元件 |
|
||
| **圖標** | Font Awesome 6 | 圖標庫 |
|
||
| **圖表** | Chart.js 4.0 | 折線圖、長條圖 |
|
||
| **表格** | DataTables | 分頁、搜尋表格 |
|
||
| **日期選擇** | Flatpickr | 日期/時間選擇器 |
|
||
| **通知** | Toastr | Toast 通知 |
|
||
| **模態框** | Bootstrap Modal | 彈窗對話框 |
|
||
|
||
### 頁面載入方式
|
||
|
||
```
|
||
Server-Side Rendering (SSR)
|
||
├── Jinja2 模板渲染
|
||
├── AJAX API 呼叫 (資料更新)
|
||
└── 無 SPA 框架
|
||
```
|
||
|
||
---
|
||
|
||
## 🗄️ 資料庫架構
|
||
|
||
### 雙資料庫策略
|
||
|
||
| 環境 | 資料庫 | 用途 |
|
||
|------|--------|------|
|
||
| 開發 | SQLite | 本地快速開發 |
|
||
| 生產 | PostgreSQL | UAT + 正式環境 |
|
||
|
||
### 連線管理
|
||
|
||
```python
|
||
# database/manager.py
|
||
- 支援 SQLite 和 PostgreSQL 切換
|
||
- 連線池管理
|
||
- Session 生命週期管理
|
||
```
|
||
|
||
### 資料庫備份
|
||
|
||
- **頻率**: 每日自動備份
|
||
- **保留**: 最近 7 天
|
||
- **工具**: pg_dump + cron
|
||
|
||
---
|
||
|
||
## 🚀 部署架構
|
||
|
||
### K3s Kubernetes 環境
|
||
|
||
```yaml
|
||
Namespace: momo
|
||
├── Deployment: momo-app (Flask)
|
||
│ ├── Replicas: 1
|
||
│ ├── Resources: 512Mi-4Gi / 200m-2000m
|
||
│ └── Image: harbor.wooo.work/wooo/momo-pro-system
|
||
│
|
||
├── Deployment: momo-scheduler (爬蟲)
|
||
│ ├── Replicas: 1
|
||
│ └── Resources: 256Mi-2Gi / 100m-1000m
|
||
│
|
||
├── StatefulSet: momo-postgres
|
||
│ ├── Storage: 10Gi PVC
|
||
│ └── Resources: 256Mi-1Gi / 100m-500m
|
||
│
|
||
└── Services
|
||
├── momo-app: ClusterIP
|
||
└── momo-postgres: ClusterIP
|
||
```
|
||
|
||
### 流量路徑
|
||
|
||
```
|
||
用戶 → mo.wooo.work:443
|
||
→ VM Nginx (SSL)
|
||
→ K8s ClusterIP 10.43.238.49:80
|
||
→ momo-app Pod
|
||
```
|
||
|
||
---
|
||
|
||
## 🔄 CI/CD 流程
|
||
|
||
```mermaid
|
||
graph LR
|
||
A[Git Push] --> B[GitLab CI]
|
||
B --> C{Test}
|
||
C -->|Pass| D[Build Image]
|
||
C -->|Fail| E[Auto Repair]
|
||
D --> F[Push to Harbor]
|
||
F --> G[K8s Rollout]
|
||
G --> H[Health Check]
|
||
E --> C
|
||
```
|
||
|
||
### Pipeline 階段
|
||
|
||
| 階段 | 動作 | 自動修復 |
|
||
|------|------|---------|
|
||
| test | pytest 單元測試 | 系統診斷 |
|
||
| build | Docker 映像構建 | Harbor 重啟、磁碟清理 |
|
||
| deploy | K8s 滾動更新 | Pod 重啟、Secret 重建 |
|
||
|
||
---
|
||
|
||
## 🤖 AI 服務架構
|
||
|
||
### 雙 AI 提供者
|
||
|
||
| 提供者 | 模型 | 用途 | 計費 |
|
||
|--------|------|------|------|
|
||
| **Ollama** | llama3:70b | 文案生成、推薦 | 免費 (自建) |
|
||
| **Gemini** | gemini-1.5-flash | 網路搜尋、產品分析 | 按 Token |
|
||
|
||
### AI 服務切換邏輯
|
||
|
||
```python
|
||
class AIProvider:
|
||
def generate(self, prompt):
|
||
if self.provider == 'ollama':
|
||
return self.ollama_service.generate(prompt)
|
||
else:
|
||
return self.gemini_service.generate(prompt)
|
||
```
|
||
|
||
### Ollama 伺服器
|
||
|
||
- **位置**: 192.168.0.188:11434
|
||
- **模型**: llama3:70b-instruct-q2_K
|
||
- **監控**: n8n 健康檢查 (每 5 分鐘)
|
||
|
||
---
|
||
|
||
## 📊 監控系統
|
||
|
||
### 監控堆疊
|
||
|
||
```
|
||
Prometheus (指標收集)
|
||
├── Node Exporter (主機指標)
|
||
├── cAdvisor (容器指標)
|
||
├── Postgres Exporter (DB 指標)
|
||
└── Blackbox Exporter (外部探測)
|
||
│
|
||
▼
|
||
Alertmanager (告警路由)
|
||
│
|
||
▼
|
||
Telegram / LINE (通知)
|
||
│
|
||
▼
|
||
Grafana (視覺化儀表板)
|
||
```
|
||
|
||
### 告警規則
|
||
|
||
| 規則 | 條件 | 動作 |
|
||
|------|------|------|
|
||
| Pod OOMKilled | Pod 記憶體不足 | Telegram 告警 |
|
||
| 高重啟率 | 5 分鐘內重啟 > 3 次 | Telegram 告警 |
|
||
| 磁碟空間 | 使用率 > 80% | 自動清理 |
|
||
| SSL 到期 | 30 天內到期 | 每日提醒 |
|
||
|
||
---
|
||
|
||
## 🔒 安全架構
|
||
|
||
### 認證與授權
|
||
|
||
| 項目 | 實作 |
|
||
|------|------|
|
||
| 用戶認證 | Flask-Login + Session |
|
||
| 密碼儲存 | bcrypt 雜湊 |
|
||
| CSRF 防護 | Flask-WTF Token |
|
||
| 權限控制 | RBAC (admin/manager/user) |
|
||
|
||
### 網路安全
|
||
|
||
| 項目 | 實作 |
|
||
|------|------|
|
||
| HTTPS | Let's Encrypt SSL |
|
||
| 端口限制 | 僅開放 22, 80, 443 |
|
||
| 內部服務 | 僅綁定 127.0.0.1 |
|
||
|
||
---
|
||
|
||
## 📁 外部整合
|
||
|
||
| 服務 | 用途 | 整合方式 |
|
||
|------|------|---------|
|
||
| **Google Drive** | 檔案匯入 | OAuth 2.0 API |
|
||
| **SMTP** | 郵件發送 | smtplib |
|
||
| **Telegram** | 通知 + Bot | Bot API |
|
||
| **LINE** | 通知 | Messaging API |
|
||
| **MOMO** | 商品爬蟲 | Selenium |
|
||
| **mybest** | 趨勢爬蟲 | BeautifulSoup |
|
||
|
||
---
|
||
|
||
## ⚙️ 環境變數
|
||
|
||
```bash
|
||
# 資料庫
|
||
DATABASE_URL=postgresql://user:pass@host:5432/db
|
||
SQLALCHEMY_DATABASE_URI=...
|
||
|
||
# AI 服務
|
||
OLLAMA_HOST=http://192.168.0.188:11434
|
||
OLLAMA_MODEL=llama3:70b-instruct-q2_K
|
||
GEMINI_API_KEY=AIzaSy...
|
||
|
||
# 通知
|
||
TELEGRAM_BOT_TOKEN=807564...
|
||
TELEGRAM_CHAT_ID=561907...
|
||
|
||
# Google
|
||
GOOGLE_DRIVE_FOLDER_ID=...
|
||
```
|