#!/bin/bash ############################################################################### # DesignHub 公网服务器自动化部署脚本 # 服务器: 45.192.99.48 # 使用方法: bash deploy_to_public_server.sh ############################################################################### set -e # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # 服务器配置 SERVER_IP="45.192.99.48" SERVER_PORT="22" SERVER_USER="root" SERVER_PASSWORD="1blZllMIp7" # 应用配置 APP_NAME="designhub" APP_DIR="/opt/${APP_NAME}" DB_NAME="designhub" DB_USER="designhub" DB_PASSWORD="DesignHub@2025_DB" REDIS_PASSWORD="DesignHub@2025_Redis" MYSQL_ROOT_PASSWORD="DesignHub@2025_Root" echo "========================================" echo -e "${GREEN} DesignHub 公网服务器部署脚本${NC}" echo "========================================" echo "" echo "服务器信息:" echo " IP: ${SERVER_IP}" echo " 端口: ${SERVER_PORT}" echo " 用户: ${SERVER_USER}" echo "" # 检查 sshpass 是否安装 check_sshpass() { if ! command -v sshpass &> /dev/null; then echo -e "${YELLOW}正在安装 sshpass...${NC}" if [[ "$OSTYPE" == "darwin"* ]]; then brew install hudochenkov/sshpass/sshpass 2>/dev/null || { echo -e "${RED}请先安装 sshpass: brew install hudochenkov/sshpass/sshpass${NC}" exit 1 } else sudo apt-get install -y sshpass 2>/dev/null || sudo yum install -y sshpass 2>/dev/null fi fi echo -e "${GREEN}✓ sshpass 已就绪${NC}" } # SSH 命令封装 ssh_cmd() { sshpass -p "${SERVER_PASSWORD}" ssh -p ${SERVER_PORT} \ -o StrictHostKeyChecking=no \ -o UserKnownHostsFile=/dev/null \ -o ConnectTimeout=30 \ ${SERVER_USER}@${SERVER_IP} "$@" } # SCP 命令封装 scp_cmd() { sshpass -p "${SERVER_PASSWORD}" scp -P ${SERVER_PORT} \ -o StrictHostKeyChecking=no \ -o UserKnownHostsFile=/dev/null \ "$@" } # rsync 命令封装 rsync_cmd() { sshpass -p "${SERVER_PASSWORD}" rsync -avz \ -e "ssh -p ${SERVER_PORT} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" \ "$@" } # 测试连接 test_connection() { echo -e "${BLUE}[0/10] 测试服务器连接...${NC}" if ssh_cmd "echo 'Connection successful'" 2>/dev/null; then echo -e "${GREEN}✓ 服务器连接成功${NC}" else echo -e "${RED}✗ 无法连接到服务器${NC}" exit 1 fi echo "" } # 步骤1:安装系统依赖 install_dependencies() { echo -e "${BLUE}[1/10] 安装系统依赖...${NC}" ssh_cmd << 'ENDSSH' set -e # 安装基础工具 echo "安装基础工具..." dnf install -y -q curl wget git unzip # 检查并安装 Java 17 if ! command -v java &> /dev/null || ! java -version 2>&1 | grep -q "17"; then echo "安装 Java 17..." dnf install -y -q java-17-openjdk java-17-openjdk-devel fi # 检查并安装 Maven if ! command -v mvn &> /dev/null; then echo "安装 Maven..." dnf install -y -q maven fi # 检查并安装 MySQL if ! command -v mysql &> /dev/null; then echo "安装 MySQL..." dnf install -y -q mysql-server mysql systemctl enable mysqld systemctl start mysqld sleep 3 # 设置root密码 mysqladmin -u root password "${MYSQL_ROOT_PASSWORD}" 2>/dev/null || mysqladmin -u root password "${MYSQL_ROOT_PASSWORD}" fi # 检查并安装 Redis if ! command -v redis-cli &> /dev/null; then echo "安装 Redis..." dnf install -y -q redis systemctl enable redis systemctl start redis fi # Nginx 已安装,检查状态 systemctl enable nginx || true systemctl start nginx || true # Node.js 和 pnpm 已安装,跳过 echo "✓ 系统依赖安装完成" ENDSSH echo -e "${GREEN}✓ 系统依赖安装完成${NC}" echo "" } # 步骤2:创建目录结构 create_directories() { echo -e "${BLUE}[2/10] 创建目录结构...${NC}" ssh_cmd << ENDSSH set -e mkdir -p ${APP_DIR}/{backend,frontend,logs,uploads} mkdir -p /etc/nginx/conf.d echo "✓ 目录创建完成" ENDSSH echo -e "${GREEN}✓ 目录结构创建完成${NC}" echo "" } # 步骤3:配置 MySQL setup_mysql() { echo -e "${BLUE}[3/10] 配置 MySQL 数据库...${NC}" ssh_cmd << ENDSSH set -e # 启动 MySQL (CentOS使用mysqld) systemctl start mysqld || true systemctl enable mysqld || true # 等待MySQL启动 sleep 5 # 创建数据库和用户 mysql -uroot -p${MYSQL_ROOT_PASSWORD} << 'EOSQL' 2>/dev/null || mysql -uroot -p${MYSQL_ROOT_PASSWORD} << 'EOSQL' CREATE DATABASE IF NOT EXISTS ${DB_NAME} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER IF NOT EXISTS '${DB_USER}'@'localhost' IDENTIFIED BY '${DB_PASSWORD}'; GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER}'@'localhost'; FLUSH PRIVILEGES; EOSQL echo "✓ MySQL 配置完成" ENDSSH echo -e "${GREEN}✓ MySQL 配置完成${NC}" echo "" } # 步骤4:配置 Redis setup_redis() { echo -e "${BLUE}[4/10] 配置 Redis...${NC}" ssh_cmd << ENDSSH set -e # 启动 Redis (CentOS使用redis服务) systemctl start redis || true systemctl enable redis || true # 设置密码(如果还没设置) redis-cli CONFIG SET requirepass "${REDIS_PASSWORD}" 2>/dev/null || true echo "✓ Redis 配置完成" ENDSSH echo -e "${GREEN}✓ Redis 配置完成${NC}" echo "" } # 步骤5:上传后端代码 upload_backend() { echo -e "${BLUE}[5/10] 上传后端代码...${NC}" # 上传整个backend目录 rsync_cmd --exclude='target' --exclude='*.class' \ backend/ ${SERVER_USER}@${SERVER_IP}:${APP_DIR}/backend/ echo -e "${GREEN}✓ 后端代码上传完成${NC}" echo "" } # 步骤6:上传前端代码 upload_frontend() { echo -e "${BLUE}[6/10] 上传前端代码...${NC}" # 上传整个frontend目录(不包括node_modules) rsync_cmd --exclude='node_modules' --exclude='dist' \ frontend/ ${SERVER_USER}@${SERVER_IP}:${APP_DIR}/frontend/ echo -e "${GREEN}✓ 前端代码上传完成${NC}" echo "" } # 步骤7:配置后端 setup_backend() { echo -e "${BLUE}[7/10] 配置并构建后端...${NC}" ssh_cmd << ENDSSH set -e cd ${APP_DIR}/backend # 创建生产环境配置文件 cat > src/main/resources/application-prod.yml << EOF spring: datasource: url: jdbc:mysql://localhost:3306/${DB_NAME}?useUnicode=true&characterEncoding=utf8mb4&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true username: ${DB_USER} password: ${DB_PASSWORD} driver-class-name: com.mysql.cj.jdbc.Driver hikari: minimum-idle: 10 maximum-pool-size: 50 connection-timeout: 30000 idle-timeout: 600000 max-lifetime: 1800000 redis: host: localhost port: 6379 password: ${REDIS_PASSWORD} database: 0 timeout: 3000 jwt: secret: DesignHub_Prod_Secret_Key_2025_Very_Strong access-token-expiration: 7200000 refresh-token-expiration: 604800000 server: port: 5123 logging: level: root: INFO com.designhub: INFO file: name: ${APP_DIR}/logs/application.log max-size: 10MB max-history: 30 file: upload: path: ${APP_DIR}/uploads max-size: 52428800 EOF # 构建项目 echo "开始构建后端项目..." mvn clean package -DskipTests 2>&1 | tail -20 # 复制 JAR 文件 cp target/designhub-backend-1.0.0.jar ${APP_DIR}/designhub.jar echo "✓ 后端构建完成" ENDSSH echo -e "${GREEN}✓ 后端配置完成${NC}" echo "" } # 步骤8:配置前端 setup_frontend() { echo -e "${BLUE}[8/10] 配置并构建前端...${NC}" ssh_cmd << ENDSSH set -e cd ${APP_DIR}/frontend # 创建生产环境配置 cat > .env.production << EOF VITE_APP_BASE_API=http://${SERVER_IP}/api VITE_APP_TITLE=DesignHub VITE_APP_VERSION=6.0 EOF # 安装依赖 echo "安装前端依赖..." pnpm install # 构建项目 echo "构建前端项目..." pnpm build echo "✓ 前端构建完成" ENDSSH echo -e "${GREEN}✓ 前端配置完成${NC}" echo "" } # 步骤9:配置系统服务 setup_services() { echo -e "${BLUE}[9/10] 配置系统服务...${NC}" ssh_cmd << ENDSSH set -e # 配置防火墙开放5123端口 if command -v firewall-cmd &> /dev/null; then firewall-cmd --permanent --add-port=5123/tcp firewall-cmd --reload echo "✓ 防火墙端口5123已开放" elif command -v ufw &> /dev/null; then ufw allow 5123/tcp echo "✓ 防火墙端口5123已开放" else echo "未找到防火墙工具,请手动开放端口5123" fi # 创建后端服务 cat > /etc/systemd/system/designhub-backend.service << EOF [Unit] Description=DesignHub Backend Service After=network.target mysqld.service redis.service [Service] Type=simple User=root WorkingDirectory=${APP_DIR} ExecStart=/usr/bin/java -jar -Xms512m -Xmx1024m ${APP_DIR}/designhub.jar --spring.profiles.active=prod Restart=on-failure RestartSec=10 StandardOutput=append:${APP_DIR}/logs/backend.log StandardError=append:${APP_DIR}/logs/backend-error.log [Install] WantedBy=multi-user.target EOF # 创建 Nginx 配置 cat > /etc/nginx/conf.d/designhub.conf << EOF server { listen 80; server_name ${SERVER_IP}; root ${APP_DIR}/frontend/dist; index index.html; access_log ${APP_DIR}/logs/nginx-access.log; error_log ${APP_DIR}/logs/nginx-error.log; # 前端路由 location / { try_files \$uri \$uri/ /index.html; } # API 代理 location /api/ { proxy_pass http://localhost:5123/api/; proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto \$scheme; proxy_connect_timeout 600; proxy_send_timeout 600; proxy_read_timeout 600; } # 静态资源缓存 location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { expires 30d; add_header Cache-Control "public, immutable"; } gzip on; gzip_types text/plain text/css application/json application/javascript text/xml application/xml; gzip_min_length 1000; } EOF # 重新加载 systemd systemctl daemon-reload # 测试 Nginx 配置 nginx -t # 重启 Nginx systemctl restart nginx systemctl enable nginx echo "✓ 系统服务配置完成" ENDSSH echo -e "${GREEN}✓ 系统服务配置完成${NC}" echo "" } # 步骤10:启动服务 start_services() { echo -e "${BLUE}[10/10] 启动服务...${NC}" ssh_cmd << ENDSSH set -e # 启动后端服务 systemctl start designhub-backend systemctl enable designhub-backend # 等待服务启动 sleep 5 # 检查服务状态 echo "" echo "=== 服务状态 ===" systemctl status designhub-backend --no-pager -l | head -15 echo "" echo "✓ 服务启动完成" ENDSSH echo -e "${GREEN}✓ 服务启动完成${NC}" echo "" } # 显示部署信息 show_deployment_info() { echo "" echo "========================================" echo -e "${GREEN} 部署完成!${NC}" echo "========================================" echo "" echo "访问地址:" echo " http://${SERVER_IP}" echo "" echo "API 地址:" echo " http://${SERVER_IP}/api" echo "" echo "服务管理:" echo " 查看后端状态: ssh ${SERVER_USER}@${SERVER_IP} 'systemctl status designhub-backend'" echo " 查看后端日志: ssh ${SERVER_USER}@${SERVER_IP} 'tail -f ${APP_DIR}/logs/application.log'" echo " 重启后端: ssh ${SERVER_USER}@${SERVER_IP} 'systemctl restart designhub-backend'" echo "" echo "数据库信息:" echo " 数据库名: ${DB_NAME}" echo " 用户名: ${DB_USER}" echo " 密码: ${DB_PASSWORD}" echo "" } # 主执行流程 main() { check_sshpass test_connection install_dependencies create_directories setup_mysql setup_redis upload_backend upload_frontend setup_backend setup_frontend setup_services start_services show_deployment_info } # 执行主函数 main