#!/bin/bash # ============================================================================= # MOMO Pro System - 一鍵部署腳本 # ============================================================================= # 用途:將 MOMO Pro System 完整部署到新的 VM 環境 # 支援:Docker Compose 部署、K8s 部署、SSH 遠端部署、匯出部署包 # 版本:2.0.0 # 更新:2026-01-29 # ============================================================================= set -e # 腳本目錄 SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" # 載入函數庫 source "$SCRIPT_DIR/lib/common.sh" source "$SCRIPT_DIR/lib/check.sh" source "$SCRIPT_DIR/lib/config.sh" source "$SCRIPT_DIR/lib/docker.sh" source "$SCRIPT_DIR/lib/database.sh" source "$SCRIPT_DIR/lib/ssl.sh" source "$SCRIPT_DIR/lib/health.sh" # 載入新增模組 [[ -f "$SCRIPT_DIR/lib/k8s.sh" ]] && source "$SCRIPT_DIR/lib/k8s.sh" [[ -f "$SCRIPT_DIR/lib/monitoring.sh" ]] && source "$SCRIPT_DIR/lib/monitoring.sh" [[ -f "$SCRIPT_DIR/lib/systemd.sh" ]] && source "$SCRIPT_DIR/lib/systemd.sh" [[ -f "$SCRIPT_DIR/lib/harbor.sh" ]] && source "$SCRIPT_DIR/lib/harbor.sh" # ============================================================================= # 預設值 # ============================================================================= DEPLOY_MODE="local" # local | ssh | export | k8s TARGET_HOST="" # SSH 目標主機 TARGET_USER="root" # SSH 用戶 TARGET_PATH="/opt/momo-pro-system" # 遠端部署路徑 ENV_FILE="" # 自訂環境變數檔案 INCLUDE_MONITORING="true" # 是否包含監控服務 INCLUDE_DATA="false" # 是否包含資料庫備份 DOMAIN="" # 域名(用於 SSL) SKIP_CONFIRM="false" # 跳過確認提示 BACKUP_PATH="" # 備份檔案路徑(用於還原) DEPLOY_TYPE="docker" # docker | k8s SETUP_SYSTEMD="false" # 是否設定 systemd 服務 K8S_NAMESPACE="momo" # K8s 命名空間 # Harbor 設定 HARBOR_REGISTRY="${HARBOR_REGISTRY:-harbor.wooo.work}" HARBOR_USERNAME="${HARBOR_USERNAME:-admin}" HARBOR_PASSWORD="${HARBOR_PASSWORD:-Wooo_Harbor_2026}" HARBOR_PROJECT="${HARBOR_PROJECT:-wooo}" # Telegram 設定 TELEGRAM_BOT_TOKEN="${TELEGRAM_BOT_TOKEN:-8075645931:AAH-EGKMo8ZC4QJs-Nc1_0s92xHrGdQvdpg}" TELEGRAM_CHAT_ID="${TELEGRAM_CHAT_ID:-5619078117}" # ============================================================================= # 顯示使用說明 # ============================================================================= show_help() { cat << EOF ${CYAN}═══════════════════════════════════════════════════════════════════════════════${NC} ${BOLD}MOMO Pro System - 一鍵部署腳本 v2.0.0${NC} ${CYAN}═══════════════════════════════════════════════════════════════════════════════${NC} ${YELLOW}用法:${NC} ./deploy.sh [選項] [命令] ${YELLOW}基本命令:${NC} deploy 執行完整部署(預設) backup 備份現有環境(資料庫 + 配置) restore 從備份還原 check 僅執行環境檢查 export 匯出部署包(不執行部署) ssl 設定/更新 SSL 憑證 health 執行健康檢查 ${YELLOW}K8s 命令:${NC} k8s-deploy 部署到 Kubernetes 叢集 k8s-status 查看 K8s 部署狀態 k8s-logs 查看 K8s 應用日誌 k8s-rollback 回滾到上一個版本 k8s-cleanup 清理 K8s 資源 ${YELLOW}Harbor 命令:${NC} harbor-install 安裝 Harbor Registry harbor-push 建構並推送映像到 Harbor harbor-scan 觸發容器安全掃描 harbor-health 檢查 Harbor 健康狀態 ${YELLOW}監控命令:${NC} monitoring-deploy 部署監控堆疊 (Prometheus/Grafana) monitoring-status 查看監控服務狀態 ${YELLOW}系統命令:${NC} systemd-setup 設定開機自動啟動服務 systemd-status 查看 systemd 服務狀態 ${YELLOW}部署模式選項:${NC} --local 本地 Docker Compose 部署(預設) --k8s Kubernetes 部署 --ssh SSH 遠端部署 --export 匯出部署包 ${YELLOW}SSH 選項:${NC} -h, --host 目標主機 IP 或域名 -u, --user SSH 用戶名(預設: root) -p, --path 遠端部署路徑(預設: /opt/momo-pro-system) ${YELLOW}K8s 選項:${NC} -n, --namespace K8s 命名空間(預設: momo) ${YELLOW}Harbor 選項:${NC} --registry Harbor Registry URL --harbor-user Harbor 用戶名 --harbor-pass Harbor 密碼 ${YELLOW}配置選項:${NC} -e, --env-file 使用自訂環境變數檔案 -d, --domain 設定域名(用於 SSL 憑證) --no-monitoring 不部署監控服務 --with-data 包含資料庫備份(匯出/遠端部署時) --with-systemd 設定 systemd 開機自動啟動 ${YELLOW}備份/還原選項:${NC} -b, --backup 指定備份檔案路徑(還原時使用) ${YELLOW}其他選項:${NC} -y, --yes 跳過所有確認提示 --help 顯示此說明 ${YELLOW}基本範例:${NC} # 本地 Docker 部署(互動式配置) ./deploy.sh deploy # SSH 遠端部署 ./deploy.sh --ssh -h 192.168.1.100 -u wooo deploy # 匯出部署包(含資料) ./deploy.sh --export --with-data ${YELLOW}K8s 範例:${NC} # 部署到 K8s ./deploy.sh --k8s deploy # 建構映像並推送到 Harbor,然後部署到 K8s ./deploy.sh harbor-push && ./deploy.sh --k8s deploy # 查看 K8s 狀態 ./deploy.sh k8s-status # 回滾 K8s 部署 ./deploy.sh k8s-rollback ${YELLOW}監控範例:${NC} # 部署完整監控堆疊 ./deploy.sh monitoring-deploy # 查看監控狀態 ./deploy.sh monitoring-status ${YELLOW}完整部署流程:${NC} # 1. 環境檢查 ./deploy.sh check # 2. 部署應用(含 systemd 設定) ./deploy.sh --with-systemd deploy # 3. 設定 SSL ./deploy.sh -d mo.wooo.work ssl # 4. 部署監控 ./deploy.sh monitoring-deploy # 5. 健康檢查 ./deploy.sh health ${CYAN}═══════════════════════════════════════════════════════════════════════════════${NC} EOF } # ============================================================================= # 解析命令行參數 # ============================================================================= parse_args() { COMMAND="deploy" # 預設命令 while [[ $# -gt 0 ]]; do case $1 in # 基本命令 deploy|backup|restore|check|export|ssl|health) COMMAND="$1" shift ;; # K8s 命令 k8s-deploy|k8s-status|k8s-logs|k8s-rollback|k8s-cleanup) COMMAND="$1" DEPLOY_TYPE="k8s" shift ;; # Harbor 命令 harbor-install|harbor-push|harbor-scan|harbor-health) COMMAND="$1" shift ;; # 監控命令 monitoring-deploy|monitoring-status) COMMAND="$1" shift ;; # systemd 命令 systemd-setup|systemd-status) COMMAND="$1" shift ;; # 部署模式 --local) DEPLOY_MODE="local" DEPLOY_TYPE="docker" shift ;; --k8s) DEPLOY_MODE="local" DEPLOY_TYPE="k8s" shift ;; --ssh) DEPLOY_MODE="ssh" shift ;; --export) DEPLOY_MODE="export" shift ;; # SSH 選項 -h|--host) TARGET_HOST="$2" shift 2 ;; -u|--user) TARGET_USER="$2" shift 2 ;; -p|--path) TARGET_PATH="$2" shift 2 ;; # K8s 選項 -n|--namespace) K8S_NAMESPACE="$2" shift 2 ;; # Harbor 選項 --registry) HARBOR_REGISTRY="$2" shift 2 ;; --harbor-user) HARBOR_USERNAME="$2" shift 2 ;; --harbor-pass) HARBOR_PASSWORD="$2" shift 2 ;; # 配置選項 -e|--env-file) ENV_FILE="$2" shift 2 ;; -d|--domain) DOMAIN="$2" shift 2 ;; -b|--backup) BACKUP_PATH="$2" shift 2 ;; --no-monitoring) INCLUDE_MONITORING="false" shift ;; --with-data) INCLUDE_DATA="true" shift ;; --with-systemd) SETUP_SYSTEMD="true" shift ;; -y|--yes) SKIP_CONFIRM="true" shift ;; --help) show_help exit 0 ;; *) log_error "未知選項: $1" show_help exit 1 ;; esac done # 驗證 SSH 模式參數 if [[ "$DEPLOY_MODE" == "ssh" && -z "$TARGET_HOST" ]]; then log_error "SSH 模式需要指定目標主機 (-h/--host)" exit 1 fi # 驗證還原命令參數 if [[ "$COMMAND" == "restore" && -z "$BACKUP_PATH" ]]; then log_error "還原命令需要指定備份檔案路徑 (-b/--backup)" exit 1 fi # 匯出環境變數供子模組使用 export HARBOR_REGISTRY HARBOR_USERNAME HARBOR_PASSWORD HARBOR_PROJECT export K8S_NAMESPACE export TELEGRAM_BOT_TOKEN TELEGRAM_CHAT_ID export PROJECT_ROOT SKIP_CONFIRM } # ============================================================================= # 顯示部署摘要 # ============================================================================= show_summary() { echo "" log_section "部署摘要" echo "" echo " ${BOLD}命令:${NC} $COMMAND" echo " ${BOLD}部署類型:${NC} $DEPLOY_TYPE" echo " ${BOLD}部署模式:${NC} $DEPLOY_MODE" if [[ "$DEPLOY_MODE" == "ssh" ]]; then echo " ${BOLD}目標主機:${NC} ${TARGET_USER}@${TARGET_HOST}" echo " ${BOLD}遠端路徑:${NC} $TARGET_PATH" fi if [[ "$DEPLOY_TYPE" == "k8s" ]]; then echo " ${BOLD}K8s 命名空間:${NC} $K8S_NAMESPACE" echo " ${BOLD}Harbor:${NC} $HARBOR_REGISTRY" fi if [[ -n "$ENV_FILE" ]]; then echo " ${BOLD}環境變數:${NC} $ENV_FILE" fi if [[ -n "$DOMAIN" ]]; then echo " ${BOLD}域名:${NC} $DOMAIN" fi echo " ${BOLD}監控服務:${NC} $([ "$INCLUDE_MONITORING" == "true" ] && echo "✓ 包含" || echo "✗ 不包含")" echo " ${BOLD}資料備份:${NC} $([ "$INCLUDE_DATA" == "true" ] && echo "✓ 包含" || echo "✗ 不包含")" echo " ${BOLD}Systemd:${NC} $([ "$SETUP_SYSTEMD" == "true" ] && echo "✓ 設定開機啟動" || echo "✗ 不設定")" echo "" if [[ "$SKIP_CONFIRM" != "true" ]]; then read -p " 確認繼續? [y/N]: " confirm if [[ ! "$confirm" =~ ^[Yy]$ ]]; then log_info "已取消操作" exit 0 fi fi } # ============================================================================= # 執行部署 # ============================================================================= do_deploy() { log_section "開始部署 MOMO Pro System" # Step 1: 環境檢查 log_step 1 8 "環境檢查" check_prerequisites # Step 2: 準備配置 log_step 2 8 "準備配置" if [[ -n "$ENV_FILE" ]]; then validate_env_file "$ENV_FILE" else generate_env_interactive fi # Step 3: 根據模式執行不同的部署 case $DEPLOY_MODE in local) do_local_deploy ;; ssh) do_ssh_deploy ;; export) do_export_package ;; esac } # ============================================================================= # 本地部署 # ============================================================================= do_local_deploy() { log_step 3 8 "拉取 Docker 映像" docker_pull_images log_step 4 8 "啟動核心服務" docker_start_core if [[ "$INCLUDE_MONITORING" == "true" ]]; then log_step 5 8 "啟動監控服務" docker_start_monitoring else log_step 5 8 "跳過監控服務" fi log_step 6 8 "等待服務啟動" wait_for_services log_step 7 8 "匯入 n8n 工作流程" import_n8n_workflows log_step 8 8 "健康檢查" health_check_all log_success "本地部署完成!" show_access_info "localhost" } # ============================================================================= # SSH 遠端部署 # ============================================================================= do_ssh_deploy() { log_step 3 8 "測試 SSH 連線" test_ssh_connection "$TARGET_HOST" "$TARGET_USER" log_step 4 8 "同步檔案到遠端" sync_files_to_remote "$TARGET_HOST" "$TARGET_USER" "$TARGET_PATH" log_step 5 8 "遠端執行部署" ssh_execute_deploy "$TARGET_HOST" "$TARGET_USER" "$TARGET_PATH" "$INCLUDE_MONITORING" log_step 6 8 "等待遠端服務啟動" ssh_wait_for_services "$TARGET_HOST" "$TARGET_USER" log_step 7 8 "匯入 n8n 工作流程" ssh_import_n8n_workflows "$TARGET_HOST" "$TARGET_USER" log_step 8 8 "遠端健康檢查" ssh_health_check "$TARGET_HOST" log_success "SSH 遠端部署完成!" show_access_info "$TARGET_HOST" } # ============================================================================= # 匯出部署包 # ============================================================================= do_export_package() { log_step 3 5 "準備匯出目錄" EXPORT_DIR="${PROJECT_ROOT}/export_$(date +%Y%m%d_%H%M%S)" mkdir -p "$EXPORT_DIR" log_step 4 5 "複製必要檔案" copy_deploy_files "$EXPORT_DIR" if [[ "$INCLUDE_DATA" == "true" ]]; then log_info "備份資料庫..." backup_database "$EXPORT_DIR/backup" fi log_step 5 5 "建立壓縮包" PACKAGE_NAME="momo-pro-system_$(date +%Y%m%d_%H%M%S).tar.gz" tar -czf "${PROJECT_ROOT}/${PACKAGE_NAME}" -C "$(dirname "$EXPORT_DIR")" "$(basename "$EXPORT_DIR")" rm -rf "$EXPORT_DIR" log_success "部署包已匯出: ${PROJECT_ROOT}/${PACKAGE_NAME}" echo "" echo " 大小: $(du -h "${PROJECT_ROOT}/${PACKAGE_NAME}" | cut -f1)" echo "" echo " 使用方式:" echo " 1. 將檔案複製到目標主機" echo " 2. 解壓縮: tar -xzf ${PACKAGE_NAME}" echo " 3. 進入目錄: cd momo-pro-system" echo " 4. 執行部署: ./deploy/deploy.sh deploy" } # ============================================================================= # 備份 # ============================================================================= do_backup() { log_section "備份現有環境" BACKUP_DIR="${PROJECT_ROOT}/backups" mkdir -p "$BACKUP_DIR" BACKUP_NAME="momo_backup_$(date +%Y%m%d_%H%M%S)" BACKUP_FULL_PATH="${BACKUP_DIR}/${BACKUP_NAME}" mkdir -p "$BACKUP_FULL_PATH" log_step 1 4 "備份資料庫" backup_database "$BACKUP_FULL_PATH" log_step 2 4 "備份配置檔案" backup_configs "$BACKUP_FULL_PATH" log_step 3 4 "備份 n8n 工作流程" backup_n8n_workflows "$BACKUP_FULL_PATH" log_step 4 4 "建立壓縮包" tar -czf "${BACKUP_FULL_PATH}.tar.gz" -C "$BACKUP_DIR" "$BACKUP_NAME" rm -rf "$BACKUP_FULL_PATH" log_success "備份完成: ${BACKUP_FULL_PATH}.tar.gz" echo " 大小: $(du -h "${BACKUP_FULL_PATH}.tar.gz" | cut -f1)" } # ============================================================================= # 還原 # ============================================================================= do_restore() { log_section "從備份還原" if [[ ! -f "$BACKUP_PATH" ]]; then log_error "備份檔案不存在: $BACKUP_PATH" exit 1 fi log_step 1 4 "解壓縮備份" RESTORE_DIR=$(mktemp -d) tar -xzf "$BACKUP_PATH" -C "$RESTORE_DIR" BACKUP_CONTENT=$(ls "$RESTORE_DIR") log_step 2 4 "停止現有服務" docker_stop_all log_step 3 4 "還原資料庫" restore_database "${RESTORE_DIR}/${BACKUP_CONTENT}" log_step 4 4 "還原配置檔案" restore_configs "${RESTORE_DIR}/${BACKUP_CONTENT}" rm -rf "$RESTORE_DIR" log_success "還原完成!請執行 ./deploy.sh deploy 重新啟動服務" } # ============================================================================= # SSL 設定 # ============================================================================= do_ssl() { if [[ -z "$DOMAIN" ]]; then log_error "需要指定域名 (-d/--domain)" exit 1 fi log_section "設定 SSL 憑證: $DOMAIN" setup_ssl_certificate "$DOMAIN" log_success "SSL 憑證設定完成!" } # ============================================================================= # 健康檢查 # ============================================================================= do_health() { log_section "執行健康檢查" if [[ "$DEPLOY_MODE" == "ssh" && -n "$TARGET_HOST" ]]; then ssh_health_check "$TARGET_HOST" else health_check_all fi } # ============================================================================= # 環境檢查 # ============================================================================= do_check() { log_section "環境檢查" check_prerequisites log_success "環境檢查通過!" } # ============================================================================= # K8s 命令處理 # ============================================================================= do_k8s_deploy() { log_section "部署到 Kubernetes" # 檢查 K8s 環境 check_k8s_prerequisites || exit 1 # 建構並推送映像 if [[ "$SKIP_CONFIRM" != "true" ]]; then read -p " 是否先建構並推送映像到 Harbor? [y/N]: " build_first if [[ "$build_first" =~ ^[Yy]$ ]]; then k8s_build_and_push fi fi # 執行 K8s 部署 k8s_deploy_all "$K8S_NAMESPACE" # 設定 systemd (可選) if [[ "$SETUP_SYSTEMD" == "true" ]]; then log_info "K8s 環境通常不需要額外的 systemd 配置" fi log_success "K8s 部署完成!" k8s_status "$K8S_NAMESPACE" } do_k8s_status() { k8s_status "$K8S_NAMESPACE" } do_k8s_logs() { local deployment="${2:-momo-app}" k8s_logs "$K8S_NAMESPACE" "$deployment" } do_k8s_rollback() { local deployment="${2:-momo-app}" k8s_rollback "$K8S_NAMESPACE" "$deployment" } do_k8s_cleanup() { k8s_cleanup "$K8S_NAMESPACE" } # ============================================================================= # Harbor 命令處理 # ============================================================================= do_harbor_install() { install_harbor "$DOMAIN" "$HARBOR_PASSWORD" } do_harbor_push() { harbor_build_and_push "momo-pro-system" "latest" "Dockerfile" "$PROJECT_ROOT" } do_harbor_scan() { harbor_scan_image "wooo/momo-pro-system:latest" sleep 5 harbor_get_scan_report "wooo/momo-pro-system:latest" } do_harbor_health() { harbor_health_check } # ============================================================================= # 監控命令處理 # ============================================================================= do_monitoring_deploy() { log_section "部署監控堆疊" if [[ "$DEPLOY_TYPE" == "k8s" ]]; then # K8s 監控 (Helm) install_helm add_helm_repos deploy_prometheus_stack "$MONITORING_NAMESPACE" deploy_loki "$MONITORING_NAMESPACE" else # Docker 監控 deploy_docker_monitoring fi log_success "監控堆疊部署完成!" } do_monitoring_status() { if [[ "$DEPLOY_TYPE" == "k8s" ]]; then check_monitoring_health "$MONITORING_NAMESPACE" else echo "" log_section "Docker 監控服務狀態" echo "" docker ps --filter "name=momo-" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep -E "prometheus|grafana|alertmanager|loki|cadvisor|node-exporter" || echo " 無監控容器運行" echo "" fi } # ============================================================================= # Systemd 命令處理 # ============================================================================= do_systemd_setup() { setup_all_services "$PROJECT_ROOT" } do_systemd_status() { show_services_status } # ============================================================================= # 更新 do_deploy 以支援多種部署類型 # ============================================================================= do_deploy_enhanced() { log_section "開始部署 MOMO Pro System" # Step 1: 環境檢查 log_step 1 8 "環境檢查" check_prerequisites if [[ "$DEPLOY_TYPE" == "k8s" ]]; then check_k8s_prerequisites || exit 1 fi # Step 2: 準備配置 log_step 2 8 "準備配置" if [[ -n "$ENV_FILE" ]]; then validate_env_file "$ENV_FILE" else generate_env_interactive fi # Step 3: 根據部署類型和模式執行部署 case "$DEPLOY_TYPE" in k8s) do_k8s_deploy ;; docker) case $DEPLOY_MODE in local) do_local_deploy ;; ssh) do_ssh_deploy ;; export) do_export_package ;; esac ;; esac # 設定 systemd (如果指定) if [[ "$SETUP_SYSTEMD" == "true" && "$DEPLOY_TYPE" == "docker" ]]; then log_info "設定開機自動啟動..." setup_all_services "$PROJECT_ROOT" fi } # ============================================================================= # 主程式 # ============================================================================= main() { clear echo "" echo "${PURPLE}╔═══════════════════════════════════════════════════════════════════════════╗${NC}" echo "${PURPLE}║${NC} ${BOLD}MOMO Pro System - 一鍵部署工具 v2.0.0${NC} ${PURPLE}║${NC}" echo "${PURPLE}║${NC} ${DIM}WOOO TECH © 2026${NC} ${PURPLE}║${NC}" echo "${PURPLE}╚═══════════════════════════════════════════════════════════════════════════╝${NC}" echo "" parse_args "$@" # 顯示摘要(除了 help、check 和狀態查詢命令) case "$COMMAND" in check|k8s-status|k8s-logs|monitoring-status|systemd-status|harbor-health) # 這些命令不需要確認 ;; *) show_summary ;; esac # 執行對應命令 case $COMMAND in # 基本命令 deploy) do_deploy_enhanced ;; backup) do_backup ;; restore) do_restore ;; check) do_check ;; export) DEPLOY_MODE="export" do_deploy ;; ssl) do_ssl ;; health) do_health ;; # K8s 命令 k8s-deploy) do_k8s_deploy ;; k8s-status) do_k8s_status ;; k8s-logs) do_k8s_logs ;; k8s-rollback) do_k8s_rollback ;; k8s-cleanup) do_k8s_cleanup ;; # Harbor 命令 harbor-install) do_harbor_install ;; harbor-push) do_harbor_push ;; harbor-scan) do_harbor_scan ;; harbor-health) do_harbor_health ;; # 監控命令 monitoring-deploy) do_monitoring_deploy ;; monitoring-status) do_monitoring_status ;; # Systemd 命令 systemd-setup) do_systemd_setup ;; systemd-status) do_systemd_status ;; *) log_error "未知命令: $COMMAND" show_help exit 1 ;; esac echo "" } # 執行主程式 main "$@"