#!/bin/bash # ============================================================================= # 🎁 惊喜 3: 一键部署脚本 # ============================================================================= # 用途: 一键构建 + 部署整个服务台(开发/生产双模式) # 用法: # bash scripts/oneclick-deploy.sh dev # 本地开发 # bash scripts/oneclick-deploy.sh prod # 生产部署 # bash scripts/oneclick-deploy.sh prod nas # 生产部署到 NAS # bash scripts/oneclick-deploy.sh prod server # 生产部署到公司服务器 # ============================================================================= set -e # 颜色 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' PURPLE='\033[0;35m' NC='\033[0m' info() { echo -e "${BLUE}[INFO]${NC} $1"; } ok() { echo -e "${GREEN}[OK]${NC} $1"; } warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; } step() { echo -e "\n${PURPLE}━━━ $1 ━━━${NC}"; } PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)" cd "$PROJECT_ROOT" # 参数 MODE="${1:-dev}" TARGET="${2:-local}" # ============================================================================= # 0. 前置检查 # ============================================================================= step "0/6 前置检查" info "检查 Docker..." if ! command -v docker &> /dev/null; then error "Docker 未安装,请先装 Docker Desktop / Docker Engine" fi ok "Docker: $(docker --version)" info "检查 Docker Compose..." if ! command -v docker-compose &> /dev/null && ! docker compose version &> /dev/null; then error "Docker Compose 未安装" fi ok "Docker Compose: $(docker compose version 2>/dev/null || docker-compose --version)" info "检查磁盘空间..." DISK_FREE=$(df -BG . | tail -1 | awk '{print $4}' | sed 's/G//') if [ "$DISK_FREE" -lt 5 ]; then warn "可用空间 < 5GB,建议清理" fi ok "可用空间: ${DISK_FREE}G" # ============================================================================= # 1. 环境配置 # ============================================================================= step "1/6 环境配置" case "$MODE" in dev) info "模式: 开发环境" COMPOSE_FILE="docker-compose.yml" ENV_FILE="backend/.env" ;; prod) info "模式: 生产环境" COMPOSE_FILE="docker-compose.yml" ENV_FILE="backend/.env" warn "生产部署前请确认 .env 凭据已改" ;; *) error "未知模式: $MODE (支持: dev / prod)" ;; esac # 加载 .env if [ -f "$ENV_FILE" ]; then set -a # shellcheck disable=SC1090 source "$ENV_FILE" set +a ok "已加载: $ENV_FILE" else warn "$ENV_FILE 不存在,用默认" fi # ============================================================================= # 2. 代码准备 # ============================================================================= step "2/6 代码准备" info "拉取最新代码..." if [ -d .git ]; then git fetch origin 2>/dev/null || warn "无法 fetch(可能离线)" git pull --rebase 2>/dev/null || warn "无法 pull,继续" ok "代码已更新" else warn "非 Git 仓库,跳过" fi info "复制环境变量模板..." for env in .env.example backend/.env.example; do if [ -f "$env" ] && [ ! -f "${env%.example}" ]; then cp "$env" "${env%.example}" warn "已复制 $env -> ${env%.example}(请编辑填入真实凭据)" fi done # ============================================================================= # 3. 镜像构建 # ============================================================================= step "3/6 镜像构建" info "构建 4 个服务镜像..." docker compose -f "$COMPOSE_FILE" build --parallel 2>&1 | tail -30 ok "镜像构建完成" # ============================================================================= # 4. 服务启动 # ============================================================================= step "4/6 服务启动" info "启动服务..." docker compose -f "$COMPOSE_FILE" up -d 2>&1 | tail -20 # 等待后端 ready info "等待后端就绪..." for i in $(seq 1 30); do if curl -sf http://localhost:8000/health > /dev/null 2>&1; then ok "后端就绪 (用时 ${i}s)" break fi if [ $i -eq 30 ]; then error "后端 30s 内未就绪,跑: docker compose logs backend" fi sleep 1 done # ============================================================================= # 5. 健康验证 # ============================================================================= step "5/6 健康验证" info "检查服务状态..." docker compose -f "$COMPOSE_FILE" ps # 6 端检查 SERVICES=("backend" "postgres" "redis" "nginx" "frontend-admin" "frontend-agent" "frontend-h5" "frontend-portal") for svc in "${SERVICES[@]}"; do if docker compose -f "$COMPOSE_FILE" ps "$svc" 2>/dev/null | grep -q "Up"; then ok "$svc: 运行中" else warn "$svc: 未运行" fi done # 健康端点 info "健康端点测试..." HEALTH_URLS=( "http://localhost:8000/health" "http://localhost/itdesk" "http://localhost/itagent" "http://localhost/itadmin" "http://localhost/itportal" ) for url in "${HEALTH_URLS[@]}"; do if curl -sf -o /dev/null "$url"; then ok "$url ✅" else warn "$url ❌" fi done # ============================================================================= # 6. 总结 # ============================================================================= step "6/6 部署完成" echo "" echo "🎉 一键部署完成!" echo "" echo "服务地址:" echo " 📱 H5 员工端: http://localhost/itdesk/" echo " 👤 坐席工作台: http://localhost/itagent/" echo " ⚙️ 管理后台: http://localhost/itadmin/" echo " 🌐 统一入口: http://localhost/itportal/" echo " 🔌 API: http://localhost/api/" echo "" echo "运维命令:" echo " 查看日志: docker compose logs -f [service]" echo " 重启服务: docker compose restart [service]" echo " 停止: docker compose down" echo " 完全清理: docker compose down -v" echo "" echo "后续:" echo " 1. 跑安全审计: bash scripts/security-audit.sh" echo " 2. 跑健康仪表盘: python scripts/dashboard.py" echo " 3. 跑 API 文档: bash scripts/generate-api-docs.sh" echo "" ok "🎁 一键部署成功"