Files
ewoooc/docker-compose.yml
OoO ba5fe06b13
Some checks failed
CD Pipeline / deploy (push) Has been cancelled
fix: update ollama primary host
2026-06-18 14:24:55 +08:00

827 lines
28 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# =============================================================================
# WOOO TECH - Momo Pro System
# Docker Compose Configuration
# Version: 12.0
# =============================================================================
#
# 使用方式:
# 核心服務: docker-compose up -d momo-app scheduler
# 完整監控: docker-compose --profile monitoring up -d
# BI 分析: docker-compose --profile bi up -d
# 全部服務: docker-compose --profile monitoring --profile bi up -d
# 本機開發: docker-compose --profile local-dev up -d (含 Docker Nginx)
#
# CI/CD 服務 (monitoring profile):
# - Watchtower: 自動偵測 Registry 映像更新並重啟容器
# - n8n: 工作流自動化平台 (僅 UAT 環境)
#
# Docker Registry:
# - URL: registry.wooo.work (HTTPS + 認證)
# - 帳密請由部署環境的 secret / CI 變數提供,不得寫入 repo
#
# 注意事項:
# - GCP 生產環境使用 VM 原生 Nginx不需要啟動 Docker nginx
# - VM Nginx 配置位於: /etc/nginx/sites-available/momo.conf
# - 支援域名: momo.wooo.work, mo.wooo.work, mon.wooo.work
#
# =============================================================================
version: '3.8'
services:
# ===========================================================================
# Core Services
# ===========================================================================
momo-app:
build:
context: .
dockerfile: Dockerfile
# 支援兩種模式:
# 1. 本地構建: 不設定 MOMO_IMAGE 環境變數 (使用 build 區塊)
# 2. Registry 拉取: MOMO_IMAGE=registry.wooo.work/wooo/momo-pro-system
image: ${MOMO_IMAGE:-registry.wooo.work/wooo/momo-pro-system}:${VERSION:-stable}
container_name: momo-pro-system
restart: unless-stopped
cpus: "2.0"
mem_limit: 2g
labels:
- "com.centurylinklabs.watchtower.enable=true"
ports:
- "127.0.0.1:5003:80" # 僅本地連線,透過 Nginx 反向代理nginx 反代 5003
# 強制使用 gunicorn 綁定 port 80 (覆蓋 Dockerfile CMD)preload + post_fork DB pool reset 見 gunicorn.conf.py
command: ["gunicorn", "--config", "gunicorn.conf.py", "app:app"]
volumes:
# 持久化數據
- ./data:/app/data
- ./logs:/app/logs
- ./backups:/app/backups
- ./config:/app/config
# Python 程式碼 (熱更新)
- ./config.py:/app/config.py:ro
- ./app.py:/app/app.py:ro
- ./auth.py:/app/auth.py:ro
- ./docker-compose.mcp.yml:/app/docker-compose.mcp.yml:ro
- ./gunicorn.conf.py:/app/gunicorn.conf.py:ro
- ./scheduler.py:/app/scheduler.py:ro
- ./scripts:/app/scripts:ro
- ./migrations:/app/migrations:ro
- ./services:/app/services:ro
- ./routes:/app/routes:ro
- ./database:/app/database:ro
- ./utils:/app/utils:ro
- ./static:/app/static:ro
- ./web/static:/app/web/static:ro
# HTML 模板 (熱更新)
- ./templates:/app/templates:ro
- ./web/templates:/app/web/templates:ro
environment:
- FLASK_ENV=production
- PYTHONUNBUFFERED=1
- TZ=Asia/Taipei
- METABASE_URL=/metabase
- GRIST_URL=/grist
# 關閉登入驗證(開發/測試用,生產環境預設啟用登入)
- DISABLE_LOGIN=${DISABLE_LOGIN:-false}
# 資料庫設定: Docker 環境使用 PostgreSQL
- USE_POSTGRESQL=true
- POSTGRES_HOST=${POSTGRES_HOST:-postgres}
- POSTGRES_PORT=5432
- POSTGRES_USER=${POSTGRES_USER:-momo}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=${POSTGRES_DB:-momo_analytics}
# Ollama 主機GCP-A → GCP-B → 111 自動備援ADR-028
- OLLAMA_HOST_PRIMARY=${OLLAMA_HOST_PRIMARY:-http://34.87.90.216:11434}
- OLLAMA_HOST_SECONDARY=${OLLAMA_HOST_SECONDARY:-http://34.21.145.224:11434}
- OLLAMA_HOST_FALLBACK=${OLLAMA_HOST_FALLBACK:-http://192.168.0.111:11434}
# EMBEDDING_HOST 若未設定,由 resolve_ollama_host() 自動決定(三主機級聯)
- EMBEDDING_HOST=${EMBEDDING_HOST:-}
# Gemini 只能作緊急備援;即使 .env 有 API key預設也不得產生付費出站。
- GEMINI_API_HARD_DISABLED=${GEMINI_API_HARD_DISABLED:-true}
- GEMINI_FALLBACK_ENABLED=${GEMINI_FALLBACK_ENABLED:-false}
# PPT 視覺 QA + 線上預覽:需要容器內 LibreOfficeDockerfile 安裝 libreoffice-impress
- PPT_VISION_ENABLED=${PPT_VISION_ENABLED:-true}
- PPT_VISION_MODEL=${PPT_VISION_MODEL:-minicpm-v:latest}
# ADR-020: Code Review 全自動修復主開關
# 預設 true任何 finding 一律觸發 AiderHeal可在 .env 顯式設 false 即時切斷
- CODE_REVIEW_AUTO_FIX_ENABLED=${CODE_REVIEW_AUTO_FIX_ENABLED:-true}
env_file:
- .env
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:80/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
# ADR-011: 生產主機使用獨立的 momo-db不依賴 compose postgres
networks:
- momo-network
- momo-pro_default
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ---------------------------------------------------------------------------
# [DEPRECATED] Docker Nginx - 已改用 VM 原生 Nginx
# GCP 生產環境現在使用 VM 上安裝的 Nginx配置位於:
# /etc/nginx/sites-available/momo.conf
# 支援的域名:
# - momo.wooo.work / mo.wooo.work => Flask App (port 5001)
# - mon.wooo.work => Grafana (port 3000)
# 保留此服務供本機開發使用,生產環境請勿啟動
# ---------------------------------------------------------------------------
nginx:
image: nginx:alpine
container_name: momo-nginx
restart: unless-stopped
profiles:
- local-dev # 只在本機開發時使用
ports:
- "80:80"
- "443:443"
volumes:
- ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./docker/nginx/conf.d:/etc/nginx/conf.d:ro
- ./docker/nginx/html:/usr/share/nginx/html:ro
- ./logs/nginx:/var/log/nginx
# SSL 證書 (本機使用自簽名證書)
- ./docker/nginx/ssl:/etc/letsencrypt:ro
- ./docker/certbot/conf:/etc/letsencrypt-new:ro
# Let's Encrypt ACME challenge
- ./docker/certbot/www:/var/www/certbot:ro
# 應用靜態資源
- ./static:/app/static:ro
- ./web/static:/app/web/static:ro
depends_on:
- momo-app
networks:
- momo-network
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ---------------------------------------------------------------------------
# [DEPRECATED] Nginx Monitor - 已整合到主 nginx
# 監控路由現在直接在 momo-nginx 的 mon.wooo.work 配置中處理
# 保留此服務以供過渡期間使用,將於下個版本移除
# ---------------------------------------------------------------------------
nginx-monitor:
image: nginx:alpine
container_name: momo-nginx-monitor
restart: unless-stopped
profiles:
- deprecated
ports:
- "8082:80"
volumes:
- ./docker/nginx-monitor/nginx.conf:/etc/nginx/nginx.conf:ro
- ./docker/nginx-monitor/conf.d:/etc/nginx/conf.d:ro
- ./docker/nginx-monitor/html:/usr/share/nginx/html:ro
- ./logs/nginx-monitor:/var/log/nginx
networks:
- momo-network
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ---------------------------------------------------------------------------
# Scheduler - 排程服務 (商品看板、活動看板、Google Drive 自動匯入)
# ---------------------------------------------------------------------------
scheduler:
build:
context: .
dockerfile: Dockerfile
image: ${MOMO_IMAGE:-registry.wooo.work/wooo/momo-pro-system}:${VERSION:-stable}
container_name: momo-scheduler
restart: unless-stopped
cpus: "2.0"
mem_limit: 2g
labels:
- "com.centurylinklabs.watchtower.enable=true"
init: true # 使用 tini 作為 init 進程,自動回收僵屍進程
volumes:
- ./data:/app/data
- ./logs:/app/logs
- ./config:/app/config # Google Drive 認證檔案 (需要寫入權限以更新 token)
- ./config.py:/app/config.py:ro
- ./scheduler.py:/app/scheduler.py:ro
- ./run_scheduler.py:/app/run_scheduler.py:ro
- ./services:/app/services:ro
- ./routes:/app/routes:ro
- ./database:/app/database:ro # 資料庫模型
- ./utils:/app/utils:ro
environment:
- FLASK_ENV=production
- PYTHONUNBUFFERED=1
- TZ=Asia/Taipei
# 資料庫設定: Docker 環境使用 PostgreSQL
# H7 (2026-04-24): POSTGRES_* 改由 env_file: .env 唯一來源,移除 compose 層插值避免空值覆蓋
- USE_POSTGRESQL=true
- POSTGRES_PORT=5432
# Ollama 主機GCP-A → GCP-B → 111 自動備援ADR-028
- OLLAMA_HOST_PRIMARY=${OLLAMA_HOST_PRIMARY:-http://34.87.90.216:11434}
- OLLAMA_HOST_SECONDARY=${OLLAMA_HOST_SECONDARY:-http://34.21.145.224:11434}
- OLLAMA_HOST_FALLBACK=${OLLAMA_HOST_FALLBACK:-http://192.168.0.111:11434}
- EMBEDDING_HOST=${EMBEDDING_HOST:-}
# Gemini 只能作緊急備援;即使 .env 有 API key預設也不得產生付費出站。
- GEMINI_API_HARD_DISABLED=${GEMINI_API_HARD_DISABLED:-true}
- GEMINI_FALLBACK_ENABLED=${GEMINI_FALLBACK_ENABLED:-false}
- PPT_VISION_ENABLED=${PPT_VISION_ENABLED:-true}
- PPT_VISION_MODEL=${PPT_VISION_MODEL:-minicpm-v:latest}
env_file:
- .env
command: ["python", "run_scheduler.py"]
healthcheck:
test: ["CMD", "python3", "-c", "import sys; sys.exit(0)"]
interval: 60s
timeout: 10s
retries: 3
start_period: 30s
depends_on:
- momo-app
# ADR-011: postgres 移除(生產用 momo-db
networks:
- momo-network
- momo-pro_default
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ---------------------------------------------------------------------------
# Telegram Bot - 互動指令 + 每日 09:00 推播
# ---------------------------------------------------------------------------
telegram-bot:
build:
context: .
dockerfile: Dockerfile
image: ${MOMO_IMAGE:-registry.wooo.work/wooo/momo-pro-system}:${VERSION:-stable}
container_name: momo-telegram-bot
restart: unless-stopped
cpus: "0.5"
mem_limit: 512m
labels:
- "com.centurylinklabs.watchtower.enable=true"
init: true
volumes:
- ./data:/app/data
- ./logs:/app/logs
- ./config:/app/config
- ./config.py:/app/config.py:ro
- ./run_telegram_bot.py:/app/run_telegram_bot.py:ro
- ./services:/app/services:ro
- ./routes:/app/routes:ro
- ./database:/app/database:ro
- ./utils:/app/utils:ro
environment:
- FLASK_ENV=production
- PYTHONUNBUFFERED=1
- TZ=Asia/Taipei
# H7 (2026-04-24): POSTGRES_* 改由 env_file: .env 唯一來源,移除 compose 層插值避免空值覆蓋
- USE_POSTGRESQL=true
- POSTGRES_PORT=5432
# Ollama 主機GCP-A → GCP-B → 111 自動備援ADR-028
- OLLAMA_HOST_PRIMARY=${OLLAMA_HOST_PRIMARY:-http://34.87.90.216:11434}
- OLLAMA_HOST_SECONDARY=${OLLAMA_HOST_SECONDARY:-http://34.21.145.224:11434}
- OLLAMA_HOST_FALLBACK=${OLLAMA_HOST_FALLBACK:-http://192.168.0.111:11434}
- EMBEDDING_HOST=${EMBEDDING_HOST:-}
# Gemini 只能作緊急備援;即使 .env 有 API key預設也不得產生付費出站。
- GEMINI_API_HARD_DISABLED=${GEMINI_API_HARD_DISABLED:-true}
- GEMINI_FALLBACK_ENABLED=${GEMINI_FALLBACK_ENABLED:-false}
env_file:
- .env
command: ["python", "run_telegram_bot.py"]
healthcheck:
test: ["CMD", "python3", "-c", "import sys; sys.exit(0)"]
interval: 60s
timeout: 10s
retries: 3
start_period: 30s
# ADR-011: postgres depends_on 移除(生產用 momo-db
networks:
- momo-network
- momo-pro_default
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ===========================================================================
# Monitoring Services (使用 --profile monitoring 啟用)
# ===========================================================================
# ---------------------------------------------------------------------------
# Prometheus - 指標收集與儲存
# ---------------------------------------------------------------------------
prometheus:
image: prom/prometheus:v2.47.0
container_name: momo-prometheus
restart: unless-stopped
profiles:
- monitoring
ports:
- "127.0.0.1:9090:9090"
volumes:
- ./docker/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
- ./docker/prometheus/alert_rules.yml:/etc/prometheus/alert_rules.yml:ro
- prometheus-data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--storage.tsdb.retention.time=15d'
- '--web.console.libraries=/usr/share/prometheus/console_libraries'
- '--web.console.templates=/usr/share/prometheus/consoles'
- '--web.enable-lifecycle'
- '--web.external-url=https://mon.wooo.work/prometheus/'
- '--web.route-prefix=/'
depends_on:
- alertmanager
networks:
- momo-network
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ---------------------------------------------------------------------------
# Alertmanager - 告警管理
# ---------------------------------------------------------------------------
alertmanager:
image: prom/alertmanager:v0.26.0
container_name: momo-alertmanager
restart: unless-stopped
profiles:
- monitoring
ports:
- "9093:9093"
volumes:
- ./docker/alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro
- alertmanager-data:/alertmanager
command:
- '--config.file=/etc/alertmanager/alertmanager.yml'
- '--storage.path=/alertmanager'
- '--web.external-url=https://mon.wooo.work/alertmanager/'
networks:
- momo-network
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ---------------------------------------------------------------------------
# Node Exporter - 主機指標CPU, Memory, Disk, Network
# ---------------------------------------------------------------------------
node-exporter:
image: prom/node-exporter:v1.6.1
container_name: momo-node-exporter
restart: unless-stopped
profiles:
- monitoring
ports:
- "127.0.0.1:9100:9100" # 僅本地連線Node Exporter 會洩漏硬體資訊
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
- '--path.rootfs=/rootfs'
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
networks:
- momo-network
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ---------------------------------------------------------------------------
# Blackbox Exporter - 網站/端口/網路探測
# ---------------------------------------------------------------------------
blackbox-exporter:
image: prom/blackbox-exporter:v0.24.0
container_name: momo-blackbox-exporter
restart: unless-stopped
profiles:
- monitoring
ports:
- "9115:9115"
volumes:
- ./docker/blackbox/blackbox.yml:/etc/blackbox_exporter/config.yml:ro
command:
- '--config.file=/etc/blackbox_exporter/config.yml'
networks:
- momo-network
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ---------------------------------------------------------------------------
# cAdvisor - 容器指標監控
# ---------------------------------------------------------------------------
cadvisor:
image: gcr.io/cadvisor/cadvisor:v0.47.0
container_name: momo-cadvisor
restart: unless-stopped
profiles:
- monitoring
ports:
- "127.0.0.1:8080:8080"
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
- /dev/disk/:/dev/disk:ro
privileged: true
devices:
- /dev/kmsg
networks:
- momo-network
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ---------------------------------------------------------------------------
# Loki - 日誌聚合
# ---------------------------------------------------------------------------
loki:
image: grafana/loki:2.9.0
container_name: momo-loki
restart: unless-stopped
profiles:
- monitoring
ports:
- "3100:3100"
volumes:
- ./docker/loki/loki-config.yaml:/etc/loki/local-config.yaml:ro
- loki-data:/loki
command: -config.file=/etc/loki/local-config.yaml
networks:
- momo-network
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ---------------------------------------------------------------------------
# Promtail - 日誌收集
# ---------------------------------------------------------------------------
promtail:
image: grafana/promtail:2.9.0
container_name: momo-promtail
restart: unless-stopped
profiles:
- monitoring
volumes:
- ./docker/promtail/promtail-config.yaml:/etc/promtail/config.yaml:ro
- ./logs:/var/log/app:ro
- ./logs/nginx:/var/log/nginx:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
command: -config.file=/etc/promtail/config.yaml
depends_on:
- loki
networks:
- momo-network
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ---------------------------------------------------------------------------
# Grafana - 視覺化儀表板
# ---------------------------------------------------------------------------
grafana:
image: grafana/grafana:10.2.0
container_name: momo-grafana
restart: unless-stopped
profiles:
- monitoring
ports:
- "127.0.0.1:3000:3000"
volumes:
- grafana-data:/var/lib/grafana
- ./docker/grafana/provisioning:/etc/grafana/provisioning:ro
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
- GF_USERS_ALLOW_SIGN_UP=false
- GF_SERVER_ROOT_URL=https://mon.wooo.work/grafana/
- GF_SERVER_SERVE_FROM_SUB_PATH=true
- GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource
depends_on:
- prometheus
- loki
networks:
- momo-network
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ---------------------------------------------------------------------------
# [DEPRECATED] SQLite Web - 已停用 (改用 PostgreSQL + pgAdmin)
# ---------------------------------------------------------------------------
# sqlite-web:
# profiles:
# - deprecated
# ---------------------------------------------------------------------------
# PostgreSQL Exporter - PostgreSQL 指標監控
# ---------------------------------------------------------------------------
postgres-exporter:
image: prometheuscommunity/postgres-exporter:v0.15.0
container_name: momo-postgres-exporter
restart: unless-stopped
profiles:
- monitoring
ports:
- "9187:9187"
environment:
- DATA_SOURCE_NAME=postgresql://${POSTGRES_USER:-momo}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-momo_analytics}?sslmode=disable
depends_on:
- postgres
networks:
- momo-network
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ---------------------------------------------------------------------------
# pgAdmin - PostgreSQL 管理介面 (取代 SQLite Web)
# ---------------------------------------------------------------------------
pgadmin:
image: dpage/pgadmin4:latest
container_name: momo-pgadmin
restart: unless-stopped
profiles:
- monitoring
ports:
- "127.0.0.1:8088:80"
environment:
- PGADMIN_DEFAULT_EMAIL=${PGADMIN_EMAIL:-admin@wooo.work}
- PGADMIN_DEFAULT_PASSWORD=${PGADMIN_PASSWORD}
- PGADMIN_CONFIG_SERVER_MODE=False
volumes:
- pgadmin-data:/var/lib/pgadmin
depends_on:
- postgres
networks:
- momo-network
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ---------------------------------------------------------------------------
# Portainer - Docker 管理介面
# ---------------------------------------------------------------------------
portainer:
image: portainer/portainer-ce:latest
container_name: momo-portainer
restart: unless-stopped
profiles:
- monitoring
ports:
- "127.0.0.1:9000:9000" # 僅本地連線,透過 SSH Tunnel 存取
- "127.0.0.1:9443:9443" # 僅本地連線
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer-data:/data
networks:
- momo-network
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ---------------------------------------------------------------------------
# Watchtower - 自動更新容器 (偵測 Registry 映像更新)
# ---------------------------------------------------------------------------
watchtower:
image: containrrr/watchtower:latest
container_name: momo-watchtower
restart: unless-stopped
profiles:
- monitoring
volumes:
- /var/run/docker.sock:/var/run/docker.sock
# Registry 認證: 掛載 Docker config 讓 Watchtower 可以從 Registry 拉取映像
- /home/wooo/.docker/config.json:/config.json:ro
environment:
- WATCHTOWER_CLEANUP=true
- WATCHTOWER_POLL_INTERVAL=30 # 每 30 秒檢查一次(近即時更新)
- WATCHTOWER_INCLUDE_STOPPED=false
- WATCHTOWER_LABEL_ENABLE=true
- TZ=Asia/Taipei
- DOCKER_API_VERSION=1.44
command: --label-enable
networks:
- momo-network
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ---------------------------------------------------------------------------
# n8n - Workflow Automation (CI/CD notifications, webhooks)
# UAT only: http://192.168.0.110:5678
# ---------------------------------------------------------------------------
n8n:
image: n8nio/n8n:latest
container_name: momo-n8n
restart: unless-stopped
profiles:
- monitoring
ports:
- "127.0.0.1:5678:5678"
volumes:
- n8n-data:/home/node/.n8n
environment:
- N8N_HOST=${N8N_HOST:-192.168.0.110}
- N8N_PORT=5678
- N8N_PROTOCOL=${N8N_PROTOCOL:-http}
- WEBHOOK_URL=${N8N_WEBHOOK_BASE_URL:-http://192.168.0.110:5678/}
- GENERIC_TIMEZONE=Asia/Taipei
- TZ=Asia/Taipei
- N8N_SECURE_COOKIE=false
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=${N8N_USER:-admin}
- N8N_BASIC_AUTH_PASSWORD=${N8N_PASSWORD}
networks:
- momo-network
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ===========================================================================
# Database Services (核心服務)
# ===========================================================================
# ---------------------------------------------------------------------------
# PostgreSQL - 主要資料庫 (取代 SQLite)
# ---------------------------------------------------------------------------
postgres:
image: postgres:15-alpine
container_name: momo-postgres
restart: unless-stopped
cpus: "2.0"
mem_limit: 4g
# ADR-011: 生產主機使用獨立的 momo-db手動 docker run非 compose 管理)
# 此 service 僅供本地開發 / 一次性 migration 使用,預設不啟動。
# 啟用方式: docker compose --profile bundled-db up -d postgres
profiles:
- bundled-db
ports:
- "127.0.0.1:5432:5432" # 僅本地連線,防止資料庫暴露
volumes:
- postgres-data:/var/lib/postgresql/data
- ./docker/postgres/init:/docker-entrypoint-initdb.d:ro
- ./docker/postgres/postgresql.conf:/etc/postgresql/postgresql.conf:ro
environment:
- POSTGRES_USER=${POSTGRES_USER:-momo}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=${POSTGRES_DB:-momo_analytics}
- TZ=Asia/Taipei
command: postgres -c config_file=/etc/postgresql/postgresql.conf
# PostgreSQL 效能優化參數 (8GB RAM 伺服器)
# - shared_buffers=2GB (25% RAM)
# - work_mem=64MB (大型查詢排序)
# - effective_cache_size=6GB (75% RAM)
# - max_parallel_workers_per_gather=2 (並行查詢)
healthcheck:
test: ["CMD-SHELL", "pg_isready -U momo -d momo_analytics"]
interval: 10s
timeout: 5s
retries: 5
networks:
- momo-network
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ---------------------------------------------------------------------------
# Metabase - 自定義圖表 BI 平台
# ---------------------------------------------------------------------------
metabase:
image: metabase/metabase:v0.48.6
container_name: momo-metabase
restart: unless-stopped
profiles:
- bi
ports:
- "3001:3000"
volumes:
- metabase-data:/metabase-data
environment:
- MB_DB_TYPE=postgres
- MB_DB_DBNAME=metabase
- MB_DB_PORT=5432
- MB_DB_USER=${POSTGRES_USER:-momo}
- MB_DB_PASS=${POSTGRES_PASSWORD}
- MB_DB_HOST=postgres
- JAVA_TIMEZONE=Asia/Taipei
- MB_SITE_NAME=WOOO Analytics
- MB_SITE_URL=${MB_SITE_URL:-https://mo.wooo.work/metabase}
depends_on:
postgres:
condition: service_healthy
networks:
- momo-network
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ---------------------------------------------------------------------------
# Grist - 開源電子表格/資料庫平台
# ---------------------------------------------------------------------------
grist:
image: gristlabs/grist:latest
container_name: momo-grist
restart: unless-stopped
profiles:
- bi
ports:
- "8484:8484"
volumes:
- grist-data:/persist
environment:
- GRIST_DEFAULT_EMAIL=${GRIST_ADMIN_EMAIL:-admin@wooo.work}
- GRIST_SUPPORT_ANON=true
- GRIST_FORCE_LOGIN=false
- GRIST_HIDE_UI_ELEMENTS=helpCenter,billing,templates,multiSite,multiAccounts
- APP_HOME_URL=${GRIST_APP_HOME_URL:-https://mo.wooo.work/grist}
- TZ=Asia/Taipei
networks:
- momo-network
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# =============================================================================
# Networks
# =============================================================================
networks:
momo-network:
driver: bridge
name: momo-network
momo-pro_default:
external: true
# =============================================================================
# Volumes
# =============================================================================
volumes:
prometheus-data:
name: momo-prometheus-data
alertmanager-data:
name: momo-alertmanager-data
loki-data:
name: momo-loki-data
grafana-data:
name: momo-grafana-data
portainer-data:
name: momo-portainer-data
postgres-data:
name: momo-postgres-data
pgadmin-data:
name: momo-pgadmin-data
metabase-data:
name: momo-metabase-data
grist-data:
name: momo-grist-data
n8n-data:
name: momo-n8n-data