deploy-prod.sh 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. #!/bin/bash
  2. #
  3. # 有声书项目 - 生产环境部署脚本
  4. # 部署到 8.159.134.106:/data/ai/audio
  5. # 前端域名: book.rrbrr.com
  6. # 后端 API 域名: bookapi.rrbrr.com
  7. # 后端端口: 22622
  8. set -e
  9. REMOTE_HOST="8.159.134.106"
  10. REMOTE_PATH="/data/ai/audio"
  11. LOCAL_PROJECT="$(cd "$(dirname "$0")" && pwd)"
  12. SSH_KEY="$HOME/.ssh/id_rsa"
  13. SSH_PORT="22622"
  14. echo "=== 有声书项目 - 生产环境部署 ==="
  15. echo "时间: $(date)"
  16. echo "主机: $REMOTE_HOST"
  17. echo "路径: $REMOTE_PATH"
  18. echo "前端: book.rrbrr.com"
  19. echo "后端: bookapi.rrbrr.com:22622"
  20. echo ""
  21. # 1. 构建前端(后端使用已有的 dist)
  22. echo "=== 1. 构建前端 ==="
  23. cd "$LOCAL_PROJECT/my-uniapp-vue3"
  24. npm run build:h5
  25. echo "前端构建完成"
  26. cd "$LOCAL_PROJECT"
  27. # 2. 同步文件到服务器
  28. echo ""
  29. echo "=== 2. 同步文件到服务器 ==="
  30. # 创建临时目录
  31. TEMP_DIR="/tmp/deploy_audio_$(date +%Y%m%d_%H%M%S)"
  32. ssh -i "$SSH_KEY" -p "$SSH_PORT" root@$REMOTE_HOST "mkdir -p $TEMP_DIR"
  33. # 打包后端(使用已有的 dist,打包所有必要文件,排除 node_modules, .git, *.ts)
  34. echo "打包后端文件..."
  35. cd "$LOCAL_PROJECT/server"
  36. tar --exclude='node_modules' --exclude='.git' --exclude='test-*.js' -czf /tmp/server.tar.gz .
  37. cd "$LOCAL_PROJECT"
  38. # 打包前端
  39. echo "打包前端文件..."
  40. cd "$LOCAL_PROJECT/my-uniapp-vue3/dist"
  41. tar -czf /tmp/frontend.tar.gz .
  42. cd "$LOCAL_PROJECT"
  43. # 上传到服务器
  44. echo "上传后端..."
  45. scp -i "$SSH_KEY" -P "$SSH_PORT" /tmp/server.tar.gz root@$REMOTE_HOST:$TEMP_DIR/
  46. echo "上传前端..."
  47. scp -i "$SSH_KEY" -P "$SSH_PORT" /tmp/frontend.tar.gz root@$REMOTE_HOST:$TEMP_DIR/
  48. # 清理本地临时文件
  49. rm -f /tmp/server.tar.gz /tmp/frontend.tar.gz
  50. # 3. 在服务器上安装 Node.js(如需要)
  51. echo ""
  52. echo "=== 3. 检查并安装 Node.js ==="
  53. ssh -i "$SSH_KEY" -p "$SSH_PORT" root@$REMOTE_HOST << 'ENDSSH'
  54. set -e
  55. # 检查 Node.js 是否已安装
  56. if ! command -v node &> /dev/null; then
  57. echo "安装 Node.js 20.x..."
  58. curl -fsSL https://rpm.nodesource.com/setup_20.x | bash -
  59. dnf install -y nodejs
  60. fi
  61. echo "Node.js 版本: $(node --version)"
  62. echo "npm 版本: $(npm --version)"
  63. ENDSSH
  64. # 4. 在服务器上执行部署
  65. echo ""
  66. echo "=== 4. 执行服务器部署 ==="
  67. ssh -i "$SSH_KEY" -p "$SSH_PORT" root@$REMOTE_HOST << 'ENDSSH'
  68. set -e
  69. TEMP_DIR=$(ls -td /tmp/deploy_audio_* | head -1)
  70. REMOTE_PATH="/data/ai/audio"
  71. BACKUP_DIR="$REMOTE_PATH/backup_$(date +%Y%m%d_%H%M%S)"
  72. echo "创建备份..."
  73. mkdir -p $BACKUP_DIR
  74. if [ -d "$REMOTE_PATH/server" ]; then
  75. cp -r $REMOTE_PATH/server $BACKUP_DIR/ 2>/dev/null || true
  76. fi
  77. if [ -d "$REMOTE_PATH/frontend" ]; then
  78. cp -r $REMOTE_PATH/frontend $BACKUP_DIR/ 2>/dev/null || true
  79. fi
  80. echo "解压文件到临时目录..."
  81. cd $TEMP_DIR
  82. rm -rf server frontend
  83. mkdir -p server frontend
  84. tar -xzf server.tar.gz -C server/
  85. tar -xzf frontend.tar.gz -C frontend/
  86. echo "移动到目标目录..."
  87. rm -rf $REMOTE_PATH/server $REMOTE_PATH/frontend
  88. mv server $REMOTE_PATH/
  89. mv frontend $REMOTE_PATH/
  90. echo "验证关键文件..."
  91. ls -la $REMOTE_PATH/server/dist/ 2>/dev/null || echo "dist 目录不存在"
  92. ls -la $REMOTE_PATH/server/prisma/ 2>/dev/null || echo "prisma 目录不存在"
  93. echo "安装后端依赖..."
  94. cd $REMOTE_PATH/server
  95. npm install --production
  96. echo "复制生产环境配置..."
  97. cp $REMOTE_PATH/server/.env.production $REMOTE_PATH/server/.env
  98. echo "生成 Prisma Client..."
  99. npx prisma generate
  100. echo "清理临时文件..."
  101. rm -rf $TEMP_DIR
  102. echo "服务器部署完成!"
  103. ENDSSH
  104. # 5. 配置 Nginx
  105. echo ""
  106. echo "=== 5. 配置 Nginx ==="
  107. echo "Nginx 配置由宝塔面板管理,请手动配置:"
  108. echo "- book.rrbrr.com: /www/server/panel/vhost/nginx/book.rrbrr.com.conf"
  109. echo "- bookapi.rrbrr.com: /www/server/panel/vhost/nginx/bookapi.rrbrr.com.conf"
  110. echo "后端端口: 3100"
  111. # 6. 启动后端服务
  112. echo ""
  113. echo "=== 6. 启动后端服务 ==="
  114. ssh -i "$SSH_KEY" -p "$SSH_PORT" root@$REMOTE_HOST << 'ENDSSH'
  115. set -e
  116. cd /data/ai/audio/server
  117. # 安装 PM2(如果没有)
  118. if ! command -v pm2 &> /dev/null; then
  119. echo "安装 PM2..."
  120. npm install -g pm2
  121. fi
  122. # 停止旧服务
  123. pm2 delete server 2>/dev/null || true
  124. # 设置环境变量(使用 22622 端口)
  125. export SERVER_PORT=22622
  126. # 启动服务
  127. pm2 start dist/app.js --name server --env production
  128. # 保存并设置开机启动
  129. pm2 save
  130. pm2 startup
  131. echo "后端服务已启动 (端口 22622)!"
  132. ENDSSH
  133. echo ""
  134. echo "=== 部署完成 ==="
  135. echo "前端地址: http://book.rrbrr.com"
  136. echo "后端 API: http://bookapi.rrbrr.com/api"
  137. echo "健康检查: http://bookapi.rrbrr.com/health"