#!/bin/bash # 部署脚本 - 有声书项目 # 部署到 8.159.134.106:/data/ai # SSH端口: 22622 # 后端域名: bookapi.rrbrr.com / book.rrbrr.com (API) # 前端域名: book.rrbrr.com set -e REMOTE_HOST="8.159.134.106" REMOTE_SSH_PORT="22622" REMOTE_PATH="/data/ai" LOCAL_PROJECT="c:/Users/caoyg/ai/audio-tts/audio_codebuddy" BACKEND_PORT="3100" echo "=== 开始部署有声书项目 ===" echo "时间: $(date)" echo "主机: $REMOTE_HOST" echo "路径: $REMOTE_PATH" # 1. 构建项目 echo "" echo "=== 1. 构建项目 ===" cd "$LOCAL_PROJECT/server" npm run build echo "后端构建完成" cd "$LOCAL_PROJECT/my-uniapp-vue3" npm run build:h5 echo "前端构建完成" # 2. 同步文件到服务器 echo "" echo "=== 2. 同步文件到服务器 ===" # 创建临时目录 TEMP_DIR="/tmp/deploy_$(date +%Y%m%d_%H%M%S)" ssh -p $REMOTE_SSH_PORT root@$REMOTE_HOST "mkdir -p $TEMP_DIR" # 同步后端(先打包排除node_modules/.git/.ts/test-*.js) echo "打包后端文件..." cd "$LOCAL_PROJECT/server" tar --exclude='node_modules' --exclude='.git' --exclude='*.ts' --exclude='test-*.js' -czf /tmp/server.tar.gz . cd "$LOCAL_PROJECT" echo "同步后端文件..." scp -P $REMOTE_SSH_PORT /tmp/server.tar.gz root@$REMOTE_HOST:$TEMP_DIR/server.tar.gz # 同步前端(dist 目录) echo "同步前端文件..." scp -P $REMOTE_SSH_PORT -r "$LOCAL_PROJECT/my-uniapp-vue3/dist" root@$REMOTE_HOST:$TEMP_DIR/ # 3. 在服务器上执行部署 echo "" echo "=== 3. 执行服务器部署 ===" ssh -p $REMOTE_SSH_PORT root@$REMOTE_HOST << 'ENDSSH' set -e TEMP_DIR=$(ls -td /tmp/deploy_* | head -1) REMOTE_PATH="/data/ai" BACKUP_DIR="$REMOTE_PATH/backup_$(date +%Y%m%d_%H%M%S)" echo "创建备份..." mkdir -p $BACKUP_DIR if [ -d "$REMOTE_PATH/server" ]; then cp -r $REMOTE_PATH/server $BACKUP_DIR/ 2>/dev/null || true fi if [ -d "$REMOTE_PATH/frontend" ]; then cp -r $REMOTE_PATH/frontend $BACKUP_DIR/ 2>/dev/null || true fi echo "移动新文件到目标目录..." rm -rf $REMOTE_PATH/server $REMOTE_PATH/frontend mkdir -p $REMOTE_PATH/server $REMOTE_PATH/frontend tar -xzf $TEMP_DIR/server.tar.gz -C $REMOTE_PATH/server mv $TEMP_DIR/dist/* $REMOTE_PATH/frontend/ echo "安装后端依赖..." cd $REMOTE_PATH/server npm install --production echo "生成 Prisma Client..." npx prisma generate echo "清理临时文件..." rm -rf $TEMP_DIR echo "部署完成!" ENDSSH # 4. 配置 Nginx - 使用 html_book.rrbrr.com.conf echo "" echo "=== 4. 配置 Nginx ===" ssh -p $REMOTE_SSH_PORT root@$REMOTE_HOST << 'ENDSSH' set -e # 删除旧配置文件 rm -f /www/server/panel/vhost/nginx/book.rrbrr.com.conf # 写入 html_book.rrbrr.com.conf(80重定向到443,443处理所有流量) cat > /www/server/panel/vhost/nginx/html_book.rrbrr.com.conf << 'EOF' server { listen 80; server_name book.rrbrr.com; return 301 https://$server_name$request_uri; } server { listen 443 ssl; http2 on; server_name book.rrbrr.com; index index.html index.htm default.htm default.html; root /data/ai/frontend/build/h5; include /www/server/panel/vhost/nginx/extension/book.rrbrr.com/*.conf; #CERT-APPLY-CHECK--START include /www/server/panel/vhost/nginx/well-known/book.rrbrr.com.conf; #CERT-APPLY-CHECK--END ssl_certificate /www/server/panel/vhost/cert/book.rrbrr.com/fullchain.pem; ssl_certificate_key /www/server/panel/vhost/cert/book.rrbrr.com/privkey.pem; ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5; ssl_prefer_server_ciphers on; ssl_session_tickets on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; add_header Strict-Transport-Security "max-age=31536000"; add_header Alt-Svc 'quic=":443"; h3=":443"; h3-29=":443"; h3-27=":443";h3-25=":443"; h3-T050=":443"; h3-Q050=":443";h3-Q049=":443";h3-Q048=":443"; h3-Q046=":443"; h3-Q043=":443"'; error_page 497 https://$host$request_uri; location /api/ { proxy_pass http://127.0.0.1:3100; proxy_set_header Host $http_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; } include /www/server/panel/vhost/rewrite/html_book.rrbrr.com.conf; location ~ ^/(\.user.ini|\.htaccess|\.git|\.env|\.svn|\.project|LICENSE|README.md) { return 404; } location ~ \.well-known{ allow all; } if ( $uri ~ "^/\.well-known/.*\.(php|jsp|py|js|css|lua|ts|go|zip|tar\.gz|rar|7z|sql|bak)$" ) { return 403; } location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { expires 30d; error_log /dev/null; access_log /dev/null; } location ~ .*\.(js|css)?$ { expires 12h; error_log /dev/null; access_log /dev/null; } access_log /www/wwwlogs/book.rrbrr.com.log; error_log /www/wwwlogs/book.rrbrr.com.error.log; } EOF nginx -t && nginx -s reload echo "Nginx 配置已更新" ENDSSH # 5. 启动后端服务 echo "" echo "=== 5. 启动后端服务 ===" ssh -p $REMOTE_SSH_PORT root@$REMOTE_HOST << 'ENDSSH' cd /data/ai/server # 使用 PM2 管理进程 if ! command -v pm2 &> /dev/null; then echo "安装 PM2..." npm install -g pm2 fi # 停止旧服务 pm2 delete server 2>/dev/null || true # 启动服务(监听3100端口) PORT=3100 pm2 start dist/app.js --name server # 保存并设置开机启动 pm2 save pm2 startup echo "后端服务已启动! 端口: 3100" ENDSSH echo "" echo "=== 部署完成 ===" echo "后端地址: http://book.rrbrr.com (API via HTTPS)" echo "前端地址: https://book.rrbrr.com" echo "后端端口: 3100" echo "SSH端口: $REMOTE_SSH_PORT"