Files
ewoooc/docs/guides/devops_handbook.md
OoO a00f34ce87
All checks were successful
CD Pipeline / deploy (push) Successful in 1m5s
加入 Ollama GCP failover 診斷與 unhealthy skip
2026-05-25 14:16:51 +08:00

9.4 KiB
Raw Permalink Blame History

EwoooC 運維與自動化手冊 (DevOps Handbook)

🌐 伺服器連線

環境 主機 指令
正式 (EwoooC) 192.168.0.188 ssh -J wooo@192.168.0.110 ollama@192.168.0.188
周邊 (UAT) 192.168.0.110 ssh wooo@192.168.0.110
安全 (Kali) 192.168.0.112 ssh kali@192.168.0.112

🐋 Docker & Docker Compose 指令 (188 主機)

執行路徑:/home/ollama/momo-pro

常用操作

  • 查看狀態: docker ps | grep momo
  • 查看日誌: docker logs -f momo-pro-system --tail 100
  • 熱重載主應用: docker kill -s HUP momo-pro-system
  • 精準重建應用容器: docker compose up -d --no-deps --force-recreate momo-app
  • 精準重建排程/Telegram: docker compose up -d --no-deps --force-recreate scheduler telegram-bot
  • 全面啟動: docker compose up -d
  • 進入資料庫: docker exec -it momo-db psql -U momo

紅線:

  • 禁止使用 docker compose down--remove-orphans
  • 禁止 stop/remove/recreate momo-db;資料庫生命週期需另走明確維護流程。

影像管理

  • 重建影像: docker compose build --no-cache momo-app
  • 清理過期資源: docker system prune -f

🌐 Nginx 反向代理 (110 主機)

配置路徑:/etc/nginx/sites-enabled/momo

  • 重新載入: sudo systemctl reload nginx
  • 語法檢查: sudo nginx -t

🤖 n8n 工作流程管理 (188 主機)

  • 進入容器: docker exec -it n8n /bin/sh
  • 手動執行 Workflow: docker exec n8n n8n execute --id=<workflow_id>
  • 列出 Workflow: docker exec n8n n8n list:workflow

❄️ K8s / K3s 狀態

已撤除。EwoooC 正式 runtime 是 188 主機的 Docker Compose110 只作為 Gateway / Nginx / Gitea 等周邊服務主機。

若看到舊文件提到 Pod、Deployment、PVC 或叢集操作,先以 docs/adr/ADR-008-actual-runtime-on-188.mddocs/adr/ADR-011-cross-project-resource-isolation.md 為準,不要照抄舊叢集命令。


🏥 健康檢查與自動修復

監控腳本: /home/wooo/scripts/domain-health-monitor.sh (於 110 執行) 頻率: 每 5 分鐘

  • https://mo.wooo.work/health -> 200
  • https://monitor.wooo.work/ -> 200
  • https://registry.wooo.work/v2/ -> 401

🆘 故障排除 (Troubleshooting) - 2026-04-28 實戰總結

0. 110 → 188 SCP 報 Host key verification failed

  • 原因: 110 的 ~/.ssh/known_hosts 保留了 188 的舊 host key 或缺少目前 key導致部署檔案傳輸被 SSH 安全檢查擋下。
  • 修復: 在 110 執行 ssh-keygen -R 192.168.0.188 && ssh-keyscan -H 192.168.0.188 >> ~/.ssh/known_hosts
  • 驗證: 先把 /tmp/momo_scp_smoke.txt 從 110 傳到 188 的 /tmp,再用 ssh ollama@192.168.0.188 'cat /tmp/momo_scp_smoke.txt' 確認可讀,最後刪除 smoke 檔。
  • 紅線: 不要把正式部署指令改成長期 StrictHostKeyChecking=no;遇到 key 問題要修 known_hosts而不是關閉驗證。

1. 網站 502 Bad Gateway (Nginx 找不到後端)

  • 原因: 110 與 188 之間的 SSH 隧道中斷。
  • 檢查: 在 110 執行 curl -I http://127.0.0.1:5003/health
  • 修復: 在 110 執行 ssh -fN -L 5003:127.0.0.1:5003 ollama@192.168.0.188 重啟隧道。
  • CD 判斷: 先確認 188 內部 docker exec momo-pro-system curl http://127.0.0.1:80/health,再看外部 https://mo.wooo.work/health;若 internal 已 200 但 external 502多半是 Nginx/tunnel 短暫延遲。

2. CI/CD 報錯 parent snapshot ... not found

  • 原因: Docker Buildx 快取損壞。
  • 修復: 在 .gitea/workflows/cd.yaml 中使用 docker compose build --no-cache

3. CI/CD 報錯 No such container: momo-pro-system

  • 原因: Sync 模式使用硬編碼容器名,但容器可能已被重建或改名。
  • 修復: 先 docker compose up -d --no-deps momo-app scheduler telegram-bot 確保容器存在,再 docker compose restart momo-app scheduler telegram-bot 讓 bind-mounted Python 檔案重新載入。

4. Telegram Bot 代碼更新無效 (幽靈容器)

  • 原因: docker-compose.yml 遺漏了 /app/routes 的 Volume 掛載。
  • 檢查: docker inspect momo-telegram-bot | jq '.[0].Mounts'
  • 修復: 確保 volumes 段落包含 - ./routes:/app/routes:ro

5. Gunicorn 設定更新後仍吃舊版 image 內容

  • 原因: gunicorn.conf.py 若沒有 bind mount容器 restart 會使用 image 內建檔案host 上新版設定不會自動進入 /app/gunicorn.conf.py
  • 檢查: docker inspect momo-pro-system | jq '.[0].Mounts',確認有 /app/gunicorn.conf.py
  • 修復: docker-compose.ymlmomo-app.volumes 必須包含 - ./gunicorn.conf.py:/app/gunicorn.conf.py:ro,再走 CD rebuild 或精準 recreate app/scheduler/bot。

6. /metrics 持續出現 realtime_sales_monthly 欄位不存在 warning

  • 原因: 線上表 schema 可能比 ORM 窄ORM count 會包子查詢並引用不存在欄位。
  • 修復: metrics 只需要總筆數時使用 SELECT COUNT(*) FROM realtime_sales_monthly,不要透過 session.query(RealtimeSalesMonthly).count()

7. Rebuild 模式造成長時間 502

  • 原因: CD 若先 docker stop/rmdocker compose build --no-cachebuild 耗時會全部變成服務中斷時間。
  • 修復: rebuild 模式必須先 docker compose build --no-cache momo-app 成功,才短暫 stop/rm/recreate momo-app scheduler telegram-bot
  • 救急: 若 build 已經在跑且三應用容器已被移除,可精準執行 docker compose up -d --no-deps momo-app scheduler telegram-bot 先恢復服務;禁止使用 --remove-orphans

8. ElephantAlpha NIM 回 404

  • 原因: NVIDIA /v1/models 可能列出模型,但帳號未必可呼叫該 hosted functionproduction 曾對 Ultra 253B 回 Function ... Not found for account
  • 檢查: 在容器內用 NVIDIA_API_KEY 呼叫 https://integrate.api.nvidia.com/v1/models,再用低 max_tokens 測試目標 model。
  • 修復: ELEPHANT_ALPHA_MODEL 預設使用 nvidia/llama-3.3-nemotron-super-49b-v1.5,並保留 ELEPHANT_ALPHA_FALLBACK_MODELS

9. PostgreSQL 連線數快速升高

  • 原因: Flask routes 會頻繁建立 DatabaseManager(),若每次都產生新 engine/poolGunicorn 多 worker 會快速吃滿 PostgreSQL clients。
  • 修復: DatabaseManager(DATABASE_TYPE, DATABASE_PATH) 重用 engine/session且 PostgreSQL pool 收斂為 pool_size=2/max_overflow=3
  • 檢查: app log 應出現 使用 PostgreSQL 資料庫 (連線池已收斂)Gunicorn post_fork 仍需 dispose inherited engines。

10. OpenClaw embedding timeout

  • 原因: Hermes/Ollama 負載高或舊 /api/embeddings endpoint 慢,會讓 embedding worker 累加 retry。
  • 檢查: 看 embedding_retry_queuepending/processing/failed 分布,並測 http://192.168.0.111:11434/api/embed
  • 修復: client 預設使用官方 /api/embed;若舊節點 404/405 才 fallback /api/embeddings。必要時調整 EMBEDDING_TIMEOUT

11. /health 偶發 000 或容器 unhealthy但 app log 仍有 200

  • 原因: Blackbox 或外部探測打 Dashboard 首頁 /,會觸發商品看板與 PChome 比價重型查詢;少量 sync worker 被長請求佔滿時,輕量 /health 也會排隊逾時。
  • 檢查: docker logs momo-pro-system --since 20m | grep 'Blackbox-Exporter' 應只看到 GET /healthdocker stats momo-db 若接近多核心滿載,需同步看 pg_stat_activitylatest_momo 類查詢。
  • 修復: 188 的 monitoring/prometheus.yml 與 110 的 /home/wooo/monitoring/prometheus.yml blackbox HTTP targets 必須使用 /healthGunicorn 保持 worker_class=gthreadGUNICORN_THREADS=4preload_app=False

12. GCP-A Ollama refused / 110:11435 502

  • 快速診斷: 在 repo 根目錄執行 scripts/ops/diagnose_ollama_gcp_failover.sh。此腳本不需要 root也不會修改 nginx、Docker、GCP 或正式服務。
  • 判讀:
    • GCP-A direct /api/version 失敗且 GCP-B direct 成功primary VM、防火牆或 Ollama 服務異常;應用層會走 GCP-A → GCP-B → 111但仍需修 primary。
    • 110 proxy primary 502 且 110 proxy secondary 成功110 的 11435 固定代理 GCP-A所以 primary 掛時舊 proxy 入口會失敗;需 110 root 才能改 nginx 或 reload。
    • GCP-B embed 成功但耗時接近 30s表示 bge-m3 runner 慢但可用;若經常超過 30s應處理 GCP-B runner/CPU/模型併發,不要把 111 納入背景 embedding。
  • GCP-A 修復方向:
    • 有 GCP/SSH 權限時,先確認 VM 是否開機、Firewall 是否開 2211434、Ollama process 是否在 listen。
    • 110 現況若 ssh gcp-aport 22: Connection refused,代表目前跳板無法進主機,不能靠 momo-pro app 修復。
  • 110 proxy failover 方向:
    • 需要 rootsudo nginx -t、修改 /etc/nginx/sites-enabled/110-ollama-proxy.confsudo systemctl reload nginx
    • 若要讓 11435 在 GCP-A 掛時 fallback 到 GCP-B必須明確標註這是 proxy failover不代表 GCP-A 已恢復host health 仍應以 direct GCP-A 探針為準。
  • 紅線:
    • 不要把背景 bge-m3 任務改落 111。
    • 不要用更長 timeout 掩蓋 GCP-A refusedGCP-A 是 primary infra blocker。
    • 沒有 110 root 或 GCP SSH 權限時,只能完成診斷、文件與應用層降級,不能假裝已修復 primary。