# Momentry 系統服務安裝與管理指南 ## 概述 本文檔記錄 momentry 系統所需的所有服務,包括安裝步驟、健康檢查和管理命令。 **重要**: 請勿使用 `brew services` 命令管理服務,否則可能導致 .plist 檔案還原為預設狀態,造成系統異常。請使用 `launchctl` 命令進行管理。 --- ## 服務清單 | 服務名稱 | 安裝方式 | 用途 | 狀態 | |----------|----------|------|-------| | PostgreSQL | Homebrew | 影片元資料儲存 | 已安裝 | | Redis | Homebrew | 快取與工作佇列 | 已安裝 | | Ollama | Homebrew | 本地 LLM 推論 | 已安裝 | | Caddy | Homebrew | 網頁伺服器 (可選) | 已安裝 | | Gitea | 手動安裝 | Git 服務 | 已安裝 | | Grafana | Homebrew | 監控儀表板 | 已安裝 | | Kafka | 手動安裝 | 訊息佇列 (可選) | 已安裝 | | MariaDB | Homebrew | 資料庫 (可選) | 已安裝 | | Netdata | Homebrew | 系統監控 | 已安裝 | | PHP | Homebrew | Web 後端 | 已安裝 | | Prometheus | Homebrew | 指標收集 | 已安裝 | | SeaweedFS | 手動安裝 | 分散式儲存 (可選) | 已安裝 | | SFTPGo | 手動安裝 | SFTP 服務 | 已安裝 | | n8n | Homebrew | 工作流自動化 | 已安裝 | --- ## 必要服務 (Momentry 核心) ### 1. PostgreSQL #### 安裝 ```bash # 檢查是否已安裝 brew list postgresql@18 2>/dev/null || echo "Not installed" # 安裝 PostgreSQL 18 brew install postgresql@18 ``` #### 初始化資料庫 ```bash # 初始化資料庫 (如尚未初始化) initdb /usr/local/var/postgresql@18 # 建立 momentry 資料庫 createdb -U accusys momentry ``` #### 開機自動啟動 ```bash # 建立 plist 檔案 sudo tee /Library/LaunchDaemons/com.momentry.postgresql.plist > /dev/null <<'EOF' Label com.momentry.postgresql ProgramArguments /opt/homebrew/opt/postgresql@18/bin/pg_ctl -D /opt/homebrew/var/postgresql@18 -l /opt/homebrew/var/postgresql@18/logfile start RunAtLoad KeepAlive WorkingDirectory /opt/homebrew/var/postgresql@18 UserName accusys EOF # 載入服務 sudo launchctl load /Library/LaunchDaemons/com.momentry.postgresql.plist ``` #### 管理命令 ```bash # 啟動 sudo launchctl load /Library/LaunchDaemons/com.momentry.postgresql.plist # 停止 sudo launchctl unload /Library/LaunchDaemons/com.momentry.postgresql.plist # 重新載入 sudo launchctl unload /Library/LaunchDaemons/com.momentry.postgresql.plist sudo launchctl load /Library/LaunchDaemons/com.momentry.postgresql.plist ``` #### 健康檢查 ```bash # 方法 1: 使用 pg_isready pg_isready -h localhost -p 5432 -U accusys # 方法 2: 連線測試 psql -U accusys -h localhost -d momentry -c "SELECT 1;" # 方法 3: 檢查程序 pgrep -f "postgres.*postgresql@18" ``` --- ### 2. Redis #### 安裝 ```bash # 檢查是否已安裝 brew list redis 2>/dev/null || echo "Not installed" # 安裝 Redis brew install redis ``` #### 設定密碼 ```bash # 編輯 Redis 設定檔 vim /opt/homebrew/etc/redis.conf # 找到 requirepass 行,修改為: requirepass accusys # 或使用環境變數方式啟動 ``` #### 開機自動啟動 ```bash # 建立 plist 檔案 sudo tee /Library/LaunchDaemons/com.momentry.redis.plist > /dev/null <<'EOF' Label com.momentry.redis UserName accusys WorkingDirectory /Users/accusys/momentry/var/redis ProgramArguments /opt/homebrew/opt/redis/bin/redis-server /opt/homebrew/etc/redis.conf EnvironmentVariables REDIS_PASSWORD accusys RunAtLoad KeepAlive StandardOutPath /Users/accusys/momentry/log/redis.log StandardErrorPath /Users/accusys/momentry/log/redis.error.log EOF # 載入服務 sudo launchctl load /Library/LaunchDaemons/com.momentry.redis.plist ``` #### 管理命令 ```bash # 啟動 sudo launchctl load /Library/LaunchDaemons/com.momentry.redis.plist # 停止 sudo launchctl unload /Library/LaunchDaemons/com.momentry.redis.plist # 重啟 sudo launchctl unload /Library/LaunchDaemons/com.momentry.redis.plist sudo launchctl load /Library/LaunchDaemons/com.momentry.redis.plist # 查看狀態 launchctl list | grep com.momentry.redis # 查看日誌 tail -f /Users/accusys/momentry/log/redis.log tail -f /Users/accusys/momentry/log/redis.error.log ``` #### 健康檢查 ```bash # 方法 1: 使用 redis-cli ping redis-cli -a accusys ping # 輸出應為: PONG # 方法 2: 檢查密碼認證 redis-cli -a accusys AUTH accusys # 方法 3: 檢查程序 pgrep -f redis-server # 方法 4: 檢查連線數 redis-cli -a accusys INFO clients ``` --- ### 3. Ollama #### 安裝 ```bash # 檢查是否已安裝 which ollama || echo "Not installed" # 安裝 Ollama brew install ollama ``` #### 模型下載 ```bash # 下載 Mistral (LLM) ollama pull mistral:latest # 下載 Embedding 模型 ollama pull nomic-embed-text:latest # 驗證模型 ollama list ``` #### 開機自動啟動 ```bash # 建立 plist 檔案 sudo tee /Library/LaunchDaemons/com.momentry.ollama.plist > /dev/null <<'EOF' Label com.momentry.ollama UserName accusys WorkingDirectory /Users/accusys/momentry/var/ollama ProgramArguments /opt/homebrew/bin/ollama serve EnvironmentVariables OLLAMA_HOST 0.0.0.0:11434 OLLAMA_MODELS /Users/accusys/momentry/var/ollama/models RunAtLoad KeepAlive StandardOutPath /Users/accusys/momentry/log/ollama.log StandardErrorPath /Users/accusys/momentry/log/ollama.error.log EOF # 載入服務 sudo launchctl load /Library/LaunchDaemons/com.momentry.ollama.plist ``` #### 管理命令 ```bash # 啟動 sudo launchctl load /Library/LaunchDaemons/com.momentry.ollama.plist # 停止 sudo launchctl unload /Library/LaunchDaemons/com.momentry.ollama.plist # 重啟 sudo launchctl unload /Library/LaunchDaemons/com.momentry.ollama.plist sudo launchctl load /Library/LaunchDaemons/com.momentry.ollama.plist # 查看狀態 launchctl list | grep com.momentry.ollama # 查看日誌 tail -f /Users/accusys/momentry/log/ollama.log tail -f /Users/accusys/momentry/log/ollama.error.log ``` #### 健康檢查 ```bash # 方法 1: API 測試 curl -s http://localhost:11434/api/tags | jq '.models[].name' # 方法 2: 檢查程序 pgrep -f ollama # 方法 3: 列出模型 ollama list ``` --- ### 4. n8n (工作流自動化) #### 安裝 ```bash # 檢查是否已安裝 which n8n || echo "Not installed" # 安裝 n8n brew install n8n ``` #### 開機自動啟動 ```bash # 複製 plist 到 LaunchDaemons 目錄 sudo cp /Users/accusys/momentry_core_0.1/momentry_runtime/plist/com.momentry.n8n.main.plist /Library/LaunchDaemons/ sudo cp /Users/accusys/momentry_core_0.1/momentry_runtime/plist/com.momentry.n8n.worker.plist /Library/LaunchDaemons/ # 載入服務 sudo launchctl load /Library/LaunchDaemons/com.momentry.n8n.main.plist sudo launchctl load /Library/LaunchDaemons/com.momentry.n8n.worker.plist ``` #### 管理命令 ```bash # 啟動 sudo launchctl load /Library/LaunchDaemons/com.momentry.n8n.main.plist sudo launchctl load /Library/LaunchDaemons/com.momentry.n8n.worker.plist # 停止 sudo launchctl unload /Library/LaunchDaemons/com.momentry.n8n.main.plist sudo launchctl unload /Library/LaunchDaemons/com.momentry.n8n.worker.plist ``` #### 健康檢查 ```bash # 方法 1: API 測試 curl -s http://localhost:5678/ # 方法 2: 檢查程序 ps aux | grep n8n | grep -v grep # 方法 3: 檢查端口 lsof -i :5678 lsof -i :5690 ``` --- ## 可選服務 ### 4. Caddy (網頁伺服器) ```bash # 安裝 brew install caddy # 開機啟動 cp /opt/homebrew.mxcl.caddy.plist /Library/LaunchDaemons/ sudo launchctl load /Library/LaunchDaemons/homebrew.mxcl.caddy.plist # 健康檢查 curl -s https://localhost:2019/config/ | head -5 ``` ### 5. Grafana (監控) ```bash # 安裝 brew install grafana # 開機啟動 cp /opt/homebrew.mxcl.grafana.plist ~/Library/LaunchAgents/ launchctl load ~/Library/LaunchAgents/homebrew.mxcl.grafana.plist # 健康檢查 curl -s http://localhost:3000/api/health | jq '.' ``` ### 6. Prometheus (監控) ```bash # 安裝 brew install prometheus # 開機啟動 cp /opt/homebrew.mxcl.prometheus.plist ~/Library/LaunchAgents/ launchctl load ~/Library/LaunchAgents/homebrew.mxcl.prometheus.plist # 健康檢查 curl -s http://localhost:9090/-/healthy ``` ### 7. Netdata (系統監控) ```bash # 安裝 brew install netdata # 開機啟動 sudo brew services start netdata # 健康檢查 curl -s http://localhost:19999/api/v1/info | jq '.version' ``` --- ## 統一健康檢查腳本 建立 `/Users/accusys/momentry_core_0.1/scripts/health_check.sh`: ```bash #!/bin/bash # Momentry 系統健康檢查腳本 echo "========================================" echo "Momentry 系統健康檢查" echo "========================================" echo "" # 顏色定義 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color check_service() { local name=$1 local check_cmd=$2 if eval "$check_cmd" > /dev/null 2>&1; then echo -e "${GREEN}✓${NC} $name" return 0 else echo -e "${RED}✗${NC} $name" return 1 fi } total=0 passed=0 # 1. PostgreSQL total=$((total + 1)) check_service "PostgreSQL (localhost:5432)" "pg_isready -h localhost -p 5432 -U accusys" && passed=$((passed + 1)) # 2. Redis total=$((total + 1)) check_service "Redis (localhost:6379)" "redis-cli -a accusys ping" && passed=$((passed + 1)) # 3. Ollama total=$((total + 1)) check_service "Ollama (localhost:11434)" "curl -s http://localhost:11434/api/tags > /dev/null" && passed=$((passed + 1)) # 4. n8n total=$((total + 1)) check_service "n8n (localhost:5678)" "curl -s http://localhost:5678/ > /dev/null" && passed=$((passed + 1)) # 5. Grafana (如果安裝) if command -v grafana-server > /dev/null 2>&1; then total=$((total + 1)) check_service "Grafana (localhost:3000)" "curl -s http://localhost:3000/api/health > /dev/null" && passed=$((passed + 1)) fi # 6. Prometheus (如果安裝) if command -v prometheus > /dev/null 2>&1; then total=$((total + 1)) check_service "Prometheus (localhost:9090)" "curl -s http://localhost:9090/-/healthy > /dev/null" && passed=$((passed + 1)) fi # 7. Netdata (如果安裝) if command -v netdata > /dev/null 2>&1; then total=$((total + 1)) check_service "Netdata (localhost:19999)" "curl -s http://localhost:19999/api/v1/info > /dev/null" && passed=$((passed + 1)) fi echo "" echo "========================================" echo "結果: $passed/$total 服務正常" echo "========================================" if [ $passed -eq $total ]; then exit 0 else exit 1 fi ``` 使用方式: ```bash chmod +x scripts/health_check.sh ./scripts/health_check.sh ``` --- ## 服務管理速查表 ### 啟動服務 ```bash # PostgreSQL (需要 root 權限) sudo launchctl load /Library/LaunchDaemons/com.momentry.postgresql.plist # Redis, Ollama (需要 root 權限) sudo launchctl load /Library/LaunchDaemons/com.momentry.redis.plist sudo launchctl load /Library/LaunchDaemons/com.momentry.ollama.plist # n8n (需要 root 權限) sudo launchctl load /Library/LaunchDaemons/com.momentry.n8n.main.plist sudo launchctl load /Library/LaunchDaemons/com.momentry.n8n.worker.plist ``` ### 停止服務 ```bash # PostgreSQL sudo launchctl unload /Library/LaunchDaemons/com.momentry.postgresql.plist # Redis, Ollama sudo launchctl unload /Library/LaunchDaemons/com.momentry.redis.plist sudo launchctl unload /Library/LaunchDaemons/com.momentry.ollama.plist # n8n sudo launchctl unload /Library/LaunchDaemons/com.momentry.n8n.main.plist sudo launchctl unload /Library/LaunchDaemons/com.momentry.n8n.worker.plist ``` ### 查詢服務狀態 ```bash # 查看所有服務 launchctl list | grep -E "(postgres|redis|ollama|n8n|grafana|prometheus)" # 查看特定服務 launchctl list | grep com.momentry ``` --- ## 故障排除 ### PostgreSQL 問題 ```bash # 查看日誌 tail -f /opt/homebrew/var/postgresql@18/logfile # 重新初始化 pg_ctl -D /opt/homebrew/var/postgresql@18 stop rm -rf /opt/homebrew/var/postgresql@18 initdb -D /opt/homebrew/var/postgresql@18 # 重建資料庫 dropdb momentry createdb -U accusys momentry ``` ### Redis 問題 ```bash # 查看日誌 tail -f /opt/homebrew/var/log/redis.log # 測試連線 redis-cli -a accusys DEBUG SLEEP 1 # 重新整理 ACL redis-cli -a accusys FLUSHALL ``` ### Ollama 問題 ```bash # 查看日誌 tail -f ~/.ollama/logs/server.log # 重新下載模型 ollama pull mistral:latest ollama pull nomic-embed-text:latest # 檢查 GPU 使用情況 ollama list ``` --- ## 自動化腳本 建立 `/Users/accusys/momentry_core_0.1/scripts/service_manager.sh`: ```bash #!/bin/bash set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PLIST_DIR="$SCRIPT_DIR/../momentry_runtime/plist" action=${1:-start} service=${2:-all} start_postgresql() { echo "Starting PostgreSQL..." sudo launchctl load /Library/LaunchDaemons/com.momentry.postgresql.plist 2>/dev/null || \ echo "PostgreSQL plist not found, skipping..." } start_redis() { echo "Starting Redis..." launchctl load ~/Library/LaunchAgents/com.momentry.redis.plist 2>/dev/null || \ echo "Redis plist not found, skipping..." } start_ollama() { echo "Starting Ollama..." launchctl load ~/Library/LaunchAgents/com.momentry.ollama.plist 2>/dev/null || \ echo "Ollama plist not found, skipping..." } stop_postgresql() { echo "Stopping PostgreSQL..." sudo launchctl unload /Library/LaunchDaemons/com.momentry.postgresql.plist 2>/dev/null || true } stop_redis() { echo "Stopping Redis..." launchctl unload ~/Library/LaunchAgents/com.momentry.redis.plist 2>/dev/null || true } stop_ollama() { echo "Stopping Ollama..." launchctl unload ~/Library/LaunchAgents/com.momentry.ollama.plist 2>/dev/null || true } case $action in start) case $service in all) start_postgresql start_redis start_ollama ;; postgresql|pgsql|pg) start_postgresql ;; redis) start_redis ;; ollama) start_ollama ;; *) echo "Unknown service: $service" exit 1 ;; esac ;; stop) case $service in all) stop_ollama stop_redis stop_postgresql ;; postgresql|pgsql|pg) stop_postgresql ;; redis) stop_redis ;; ollama) stop_ollama ;; *) echo "Unknown service: $service" exit 1 ;; esac ;; restart) $0 stop $service sleep 2 $0 start $service ;; status) echo "Service Status:" echo "===============" launchctl list | grep -E "(postgres|redis|ollama)" || echo "No services found" ;; *) echo "Usage: $0 {start|stop|restart|status} [service]" echo "Services: all, postgresql, redis, ollama" exit 1 ;; esac ``` --- ## 附錄: 服務版本對應表 | 服務 | 版本 | Port | 使用者 | plist 位置 | |------|------|------|--------|-------------| | PostgreSQL | 18.1 | 5432 | accusys | /Library/LaunchDaemons/ | | Redis | 7.4.x | 6379 | accusys | /Library/LaunchDaemons/ | | Ollama | - | 11434 | accusys | /Library/LaunchDaemons/ | | n8n | 2.3.5 | 5678/5690 | accusys | /Library/LaunchDaemons/ | | Node.js (n8n) | 22.22.1 | - | - | /opt/homebrew/opt/node@22/ | | Python (Momentry) | 3.11.14 | - | - | venv/bin/python | | Caddy | 2.10.x | 2019 | root | /Library/LaunchDaemons/ | | Gitea | - | 3000 | accusys | /Library/LaunchDaemons/ | | SFTPGo | 2.7.x | 8080 | accusys | /Library/LaunchDaemons/ | | Qdrant | 1.17.x | 6333 | accusys | /Library/LaunchDaemons/ | | MongoDB | - | 27017 | accusys | /Library/LaunchDaemons/ | | MariaDB | 12.1.x | 3306 | accusys | /Library/LaunchDaemons/ | | RustDesk | - | 21115-21119 | accusys | /Library/LaunchDaemons/ | | PHP | 8.3.x | - | - | /opt/homebrew/ |