#!/bin/bash # ============================================================================= # AWOOOI Production Bootstrap Script # ============================================================================= # Phase 8: 全自動化初始腳本 # # 功能: # A. 讀取本地 .env 中的機密 # B. 產出 03-secrets.yaml 並 kubectl apply # C. 自動 git add, commit, push # # 用法: # ./scripts/bootstrap_prod.sh # # 前置條件: # - kubectl 已配置 (KUBECONFIG 指向 120 K3s) # - .env 檔案已填寫機密 # ============================================================================= set -euo pipefail # 顏色定義 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color echo -e "${BLUE}╔══════════════════════════════════════════════════════════════╗${NC}" echo -e "${BLUE}║ AWOOOI Production Bootstrap Script (Phase 8) ║${NC}" echo -e "${BLUE}╚══════════════════════════════════════════════════════════════╝${NC}" echo "" # ============================================================================= # 配置 # ============================================================================= SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" ENV_FILE="${PROJECT_ROOT}/.env" SECRETS_TEMPLATE="${PROJECT_ROOT}/k8s/awoooi-prod/03-secrets.example.yaml" SECRETS_OUTPUT="${PROJECT_ROOT}/k8s/awoooi-prod/03-secrets.yaml" K8S_NAMESPACE="awoooi-prod" # ============================================================================= # Step 1: 檢查前置條件 # ============================================================================= echo -e "${YELLOW}[1/5] 檢查前置條件...${NC}" # 檢查 .env 檔案 if [ ! -f "$ENV_FILE" ]; then echo -e "${RED}❌ 錯誤: .env 檔案不存在${NC}" echo " 請複製 .env.example 並填入機密:" echo " cp .env.example .env" exit 1 fi echo -e "${GREEN} ✓ .env 檔案存在${NC}" # 檢查 kubectl if ! command -v kubectl &> /dev/null; then echo -e "${RED}❌ 錯誤: kubectl 未安裝${NC}" exit 1 fi echo -e "${GREEN} ✓ kubectl 已安裝${NC}" # 檢查 K8s 連線 if ! kubectl cluster-info &> /dev/null; then echo -e "${RED}❌ 錯誤: 無法連接 K8s 叢集${NC}" echo " 請確認 KUBECONFIG 設定正確" exit 1 fi echo -e "${GREEN} ✓ K8s 叢集連線正常${NC}" # ============================================================================= # Step 2: 讀取 .env 並產生 secrets.yaml # ============================================================================= echo "" echo -e "${YELLOW}[2/5] 讀取 .env 並產生 K8s Secrets...${NC}" # 載入 .env set -a source "$ENV_FILE" set +a # 檢查必要的環境變數 REQUIRED_VARS=( "DATABASE_URL" "REDIS_URL" "OPENCLAW_TG_BOT_TOKEN" "OPENCLAW_TG_CHAT_ID" ) for var in "${REQUIRED_VARS[@]}"; do if [ -z "${!var:-}" ]; then echo -e "${RED}❌ 錯誤: 環境變數 $var 未設定${NC}" exit 1 fi done echo -e "${GREEN} ✓ 所有必要環境變數已設定${NC}" # 產生 secrets.yaml cat > "$SECRETS_OUTPUT" << EOF # AWOOOI Production Secrets # 自動產生於: $(date -Iseconds) # ⚠️ 此檔案包含機密,請勿提交至 Git apiVersion: v1 kind: Secret metadata: name: awoooi-secrets namespace: ${K8S_NAMESPACE} type: Opaque stringData: # 資料庫 DATABASE_URL: "${DATABASE_URL}" # Redis REDIS_URL: "${REDIS_URL}" # AI 服務 GEMINI_API_KEY: "${GEMINI_API_KEY:-}" CLAUDE_API_KEY: "${CLAUDE_API_KEY:-}" # Telegram Gateway OPENCLAW_TG_BOT_TOKEN: "${OPENCLAW_TG_BOT_TOKEN}" OPENCLAW_TG_CHAT_ID: "${OPENCLAW_TG_CHAT_ID}" OPENCLAW_TG_USER_WHITELIST: "${OPENCLAW_TG_USER_WHITELIST:-${OPENCLAW_TG_CHAT_ID}}" # Webhook 安全 WEBHOOK_HMAC_SECRET: "${WEBHOOK_HMAC_SECRET:-$(openssl rand -hex 32)}" # JWT (未來擴展) JWT_SECRET: "${JWT_SECRET:-$(openssl rand -hex 32)}" JWT_ALGORITHM: "HS256" EOF echo -e "${GREEN} ✓ 已產生 k8s/awoooi-prod/03-secrets.yaml${NC}" # ============================================================================= # Step 3: 套用 K8s Secrets # ============================================================================= echo "" echo -e "${YELLOW}[3/5] 套用 K8s Secrets 至 ${K8S_NAMESPACE}...${NC}" # 確保 namespace 存在 kubectl create namespace "$K8S_NAMESPACE" --dry-run=client -o yaml | kubectl apply -f - 2>/dev/null || true # 套用 secrets kubectl apply -f "$SECRETS_OUTPUT" --namespace="$K8S_NAMESPACE" echo -e "${GREEN} ✓ K8s Secrets 已套用${NC}" # 驗證 echo "" echo -e "${BLUE} 驗證 Secrets:${NC}" kubectl get secret awoooi-secrets -n "$K8S_NAMESPACE" -o jsonpath='{.metadata.name}' && echo " exists" # ============================================================================= # Step 4: 清理敏感檔案 (不提交到 Git) # ============================================================================= echo "" echo -e "${YELLOW}[4/5] 清理敏感檔案...${NC}" # 確保 secrets.yaml 在 .gitignore if ! grep -q "03-secrets.yaml" "${PROJECT_ROOT}/.gitignore" 2>/dev/null; then echo "k8s/awoooi-prod/03-secrets.yaml" >> "${PROJECT_ROOT}/.gitignore" echo -e "${GREEN} ✓ 已將 03-secrets.yaml 加入 .gitignore${NC}" fi # 刪除敏感檔案 rm -f "$SECRETS_OUTPUT" echo -e "${GREEN} ✓ 已刪除本地 secrets.yaml (僅保留在 K8s)${NC}" # ============================================================================= # Step 5: Git Commit & Push # ============================================================================= echo "" echo -e "${YELLOW}[5/5] Git Commit & Push...${NC}" cd "$PROJECT_ROOT" # 檢查是否有變更 if git diff --quiet && git diff --cached --quiet; then echo -e "${BLUE} ℹ 沒有變更需要提交${NC}" else git add . git commit -m "chore: Phase 8 CI/CD bootstrap - Add deploy-prod.yml GitHub Actions workflow - Add Signal Worker K8s deployment - Update Harbor image paths - Configure Telegram notification Co-Authored-By: Claude " echo -e "${GREEN} ✓ Git commit 完成${NC}" # Push git push origin main echo -e "${GREEN} ✓ Git push 完成${NC}" fi # ============================================================================= # 完成 # ============================================================================= echo "" echo -e "${GREEN}╔══════════════════════════════════════════════════════════════╗${NC}" echo -e "${GREEN}║ Bootstrap 完成! ║${NC}" echo -e "${GREEN}╚══════════════════════════════════════════════════════════════╝${NC}" echo "" echo -e "下一步:" echo -e " 1. 確認 110 主機 GitHub Runner 已啟動" echo -e " 2. 前往 GitHub Actions 查看部署狀態" echo -e " 3. 監控 Telegram 接收部署通知" echo "" echo -e "${BLUE}🔗 GitHub Actions: https://github.com/$(git remote get-url origin | sed 's/.*github.com[:/]\(.*\)\.git/\1/')/actions${NC}"