#!/bin/bash # 情绪博物馆自定义部署脚本 # 适用于指定目录结构的部署方案 # 前端: /data/www/emotion-museum # 后端: /data/builds # 日志: /data/logs/emotion-museum set -e # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' log_info() { echo -e "${GREEN}[INFO]${NC} $1" } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } log_step() { echo -e "${BLUE}[STEP]${NC} $1" } # 配置变量 FRONTEND_DIR="/data/www/emotion-museum" BACKEND_DIR="/data/builds" LOG_DIR="/data/logs/emotion-museum" PROJECT_DIR=$(pwd) # 检查目录结构 check_directories() { log_step "检查目录结构..." # 创建必要的目录 sudo mkdir -p "$FRONTEND_DIR" sudo mkdir -p "$BACKEND_DIR" sudo mkdir -p "$LOG_DIR"/{nginx,gateway,ai,user,mysql,redis,nacos} # 设置权限 sudo chown -R $USER:$USER "$FRONTEND_DIR" sudo chown -R $USER:$USER "$BACKEND_DIR" sudo chown -R $USER:$USER "$LOG_DIR" log_info "目录结构检查完成" } # 检查前端构建产物 check_frontend() { log_step "检查前端构建产物..." if [ ! -d "web/dist" ]; then log_warn "前端未构建,开始构建..." cd web npm ci npm run build cd .. fi if [ ! -d "web/dist" ]; then log_error "前端构建失败" exit 1 fi log_info "前端构建产物检查完成" } # 检查后端JAR文件 check_backend() { log_step "检查后端JAR文件..." local services=("emotion-gateway" "emotion-ai" "emotion-user") local missing_jars=() for service in "${services[@]}"; do local jar_file="backend/${service}/target/${service}-1.0.0.jar" if [ ! -f "$jar_file" ]; then missing_jars+=("$service") fi done if [ ${#missing_jars[@]} -gt 0 ]; then log_warn "以下服务的JAR文件不存在,开始构建: ${missing_jars[*]}" cd backend mvn clean package -DskipTests cd .. fi # 再次检查 for service in "${services[@]}"; do local jar_file="backend/${service}/target/${service}-1.0.0.jar" if [ ! -f "$jar_file" ]; then log_error "后端服务 $service 构建失败" exit 1 fi done log_info "后端JAR文件检查完成" } # 部署前端文件 deploy_frontend() { log_step "部署前端文件..." # 清空目标目录 sudo rm -rf "$FRONTEND_DIR"/* # 复制前端构建产物 sudo cp -r web/dist/* "$FRONTEND_DIR/" # 设置权限 sudo chown -R www-data:www-data "$FRONTEND_DIR" sudo chmod -R 755 "$FRONTEND_DIR" log_info "前端文件部署完成: $FRONTEND_DIR" } # 部署后端JAR文件 deploy_backend() { log_step "部署后端JAR文件..." local services=("emotion-gateway" "emotion-ai" "emotion-user") for service in "${services[@]}"; do local source_jar="backend/${service}/target/${service}-1.0.0.jar" local target_jar="$BACKEND_DIR/${service}.jar" # 复制JAR文件 sudo cp "$source_jar" "$target_jar" # 设置权限 sudo chown $USER:$USER "$target_jar" sudo chmod 644 "$target_jar" log_info "部署 $service: $target_jar" done log_info "后端JAR文件部署完成: $BACKEND_DIR" } # 配置环境变量 setup_environment() { log_step "配置环境变量..." if [ ! -f ".env" ]; then cat > .env << 'EOF' # 数据库配置 MYSQL_ROOT_PASSWORD=123456 MYSQL_DATABASE=emotion_museum MYSQL_USER=emotion MYSQL_PASSWORD=emotion123 # Redis配置 REDIS_PASSWORD= # Nacos配置 NACOS_AUTH_ENABLE=false # 应用配置 SPRING_PROFILES_ACTIVE=docker TZ=Asia/Shanghai # Coze API配置 (与开发环境一致) COZE_API_TOKEN=pat_GCR4qKzqpf90wMCvKsldMrB18KG3QsLDci65bZthssKsbLxu8X70BKYumleDcabO EOF fi log_info "环境变量配置完成" log_info "COZE_API_TOKEN 已配置为与开发环境一致的值" } # 启动Docker服务 start_docker_services() { log_step "启动Docker服务..." # 停止现有服务 docker-compose -f docker-compose.custom.yml down 2>/dev/null || true # 启动基础服务 log_info "启动基础服务 (MySQL, Redis, Nacos)..." docker-compose -f docker-compose.custom.yml up -d mysql redis nacos # 等待基础服务启动 log_info "等待基础服务启动..." sleep 30 # 启动应用服务 log_info "启动应用服务..." docker-compose -f docker-compose.custom.yml up -d emotion-gateway emotion-ai emotion-user # 等待应用服务启动 log_info "等待应用服务启动..." sleep 20 # 启动Nginx log_info "启动Nginx..." docker-compose -f docker-compose.custom.yml up -d nginx log_info "Docker服务启动完成" } # 验证部署 verify_deployment() { log_step "验证部署..." sleep 10 # 检查容器状态 log_info "检查容器状态..." docker-compose -f docker-compose.custom.yml ps # 检查服务健康状态 local services=( "http://localhost:9000/actuator/health:网关服务" "http://localhost:9001/actuator/health:用户服务" "http://localhost:9002/actuator/health:AI服务" "http://localhost/nginx-health:Nginx服务" ) for service_info in "${services[@]}"; do IFS=':' read -r url name <<< "$service_info" if curl -s "$url" > /dev/null; then log_info "✅ $name 正常" else log_warn "❌ $name 异常" fi done # 检查前端文件 if [ -f "$FRONTEND_DIR/index.html" ]; then log_info "✅ 前端文件部署正常" else log_warn "❌ 前端文件部署异常" fi # 检查后端JAR文件 local jar_files=("emotion-gateway.jar" "emotion-ai.jar" "emotion-user.jar") for jar in "${jar_files[@]}"; do if [ -f "$BACKEND_DIR/$jar" ]; then log_info "✅ $jar 部署正常" else log_warn "❌ $jar 部署异常" fi done log_info "部署验证完成" } # 显示部署信息 show_deployment_info() { local server_ip=$(hostname -I | awk '{print $1}' 2>/dev/null || echo "localhost") echo "" log_info "🎉 情绪博物馆部署完成!" echo "" echo "📁 部署目录:" echo " 前端文件: $FRONTEND_DIR" echo " 后端JAR: $BACKEND_DIR" echo " 日志目录: $LOG_DIR" echo "" echo "📱 访问地址:" echo " 前端应用: http://$server_ip" echo " API网关: http://$server_ip:9000" echo " Nacos: http://$server_ip:8848/nacos (nacos/nacos)" echo "" echo "🔧 管理命令:" echo " 查看状态: docker-compose -f docker-compose.custom.yml ps" echo " 查看日志: docker-compose -f docker-compose.custom.yml logs -f [服务名]" echo " 重启服务: docker-compose -f docker-compose.custom.yml restart [服务名]" echo " 停止服务: docker-compose -f docker-compose.custom.yml down" echo "" echo "📊 日志位置:" echo " Nginx: $LOG_DIR/nginx/" echo " Gateway: $LOG_DIR/gateway/" echo " AI: $LOG_DIR/ai/" echo " User: $LOG_DIR/user/" echo "" echo "📋 部署信息:" echo " 1. COZE_API_TOKEN 已配置为与开发环境一致" echo " 2. 前端文件位于: $FRONTEND_DIR" echo " 3. 后端JAR位于: $BACKEND_DIR" echo " 4. 所有日志保存在: $LOG_DIR" echo "" } # 清理函数 cleanup() { log_info "清理临时文件..." } # 设置清理陷阱 trap cleanup EXIT # 主函数 main() { echo "🚀 开始自定义部署情绪博物馆..." echo "" echo "📁 部署配置:" echo " 前端目录: $FRONTEND_DIR" echo " 后端目录: $BACKEND_DIR" echo " 日志目录: $LOG_DIR" echo "" check_directories check_frontend check_backend deploy_frontend deploy_backend setup_environment start_docker_services verify_deployment show_deployment_info } # 处理命令行参数 case "${1:-}" in "frontend") check_directories check_frontend deploy_frontend ;; "backend") check_directories check_backend deploy_backend ;; "docker") setup_environment start_docker_services verify_deployment ;; "verify") verify_deployment ;; "clean") log_info "清理部署..." docker-compose -f docker-compose.custom.yml down sudo rm -rf "$FRONTEND_DIR"/* sudo rm -f "$BACKEND_DIR"/*.jar log_info "清理完成" ;; *) main ;; esac