#!/bin/bash # X-Server Mobile 生产部署脚本 # 使用方法: ./deploy.sh [server] set -e # 配置 SERVER=${1:-"your-server.com"} # 默认服务器,可以通过参数指定 DEPLOY_USER="root" DEPLOY_PATH="/opt/x-server-mobile" FRONTEND_BUILD_DIR="./frontend/dist" BACKEND_SOURCE_DIR="./backend" # 颜色输出 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color log_info() { echo -e "${GREEN}[INFO]${NC} $1" } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } # 检查环境 check_env() { log_info "检查部署环境..." if ! command -v rsync &> /dev/null; then log_error "rsync 未安装,请先安装: apt-get install rsync" exit 1 fi if [ ! -d "$FRONTEND_BUILD_DIR" ]; then log_error "前端构建目录不存在: $FRONTEND_BUILD_DIR" log_info "请先运行: cd frontend && npm install && npm run build" exit 1 fi log_info "环境检查通过" } # 备份远程服务器 backup_remote() { log_info "备份远程服务器..." BACKUP_NAME="$(date +%Y%m%d_%H%M%S)" ssh ${DEPLOY_USER}@${SERVER} << EOF mkdir -p ${DEPLOY_PATH}/backup/${BACKUP_NAME} cp -r ${DEPLOY_PATH}/frontend ${DEPLOY_PATH}/backup/${BACKUP_NAME}/ 2>/dev/null || true cp -r ${DEPLOY_PATH}/backend ${DEPLOY_PATH}/backup/${BACKUP_NAME}/ 2>/dev/null || true echo "备份完成: ${BACKUP_NAME}" EOF log_info "备份完成: ${BACKUP_NAME}" } # 部署前端 deploy_frontend() { log_info "部署前端..." rsync -avz --delete \ --exclude='*.map' \ ${FRONTEND_BUILD_DIR}/ \ ${DEPLOY_USER}@${SERVER}:${DEPLOY_PATH}/frontend/ log_info "前端部署完成" } # 部署后端 deploy_backend() { log_info "部署后端..." rsync -avz \ --exclude='vendor/' \ --exclude='runtime/' \ --exclude='.git/' \ --exclude='*.log' \ ${BACKEND_SOURCE_DIR}/ \ ${DEPLOY_USER}@${SERVER}:${DEPLOY_PATH}/backend/ log_info "后端部署完成" } # 重启服务 restart_services() { log_info "重启服务..." ssh ${DEPLOY_USER}@${SERVER} << 'EOF' cd /opt/x-server-mobile # 重启后端容器 docker-compose -f docker-compose.prod.yml restart backend # 等待后端启动 sleep 5 # 检查容器状态 docker ps | grep x-server-backend-prod # 重载 OpenResty openresty -s reload || nginx -s reload echo "服务重启完成" EOF log_info "服务重启完成" } # 健康检查 health_check() { log_info "健康检查..." sleep 3 # 检查前端 if curl -s -o /dev/null -w "%{http_code}" http://${SERVER}/ | grep -q "200\|301\|302"; then log_info "前端检查通过" else log_warn "前端检查失败" fi # 检查 API if curl -s http://${SERVER}/api/v1/health 2>/dev/null | grep -q "ok\|success"; then log_info "API 检查通过" else log_warn "API 检查失败(可能需要登录)" fi } # 主流程 main() { echo "=========================================" echo " X-Server Mobile 生产部署脚本" echo "=========================================" echo "服务器: ${SERVER}" echo "部署路径: ${DEPLOY_PATH}" echo "" # 确认部署 read -p "确认部署到 ${SERVER}? (y/N) " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then log_info "部署已取消" exit 0 fi check_env backup_remote deploy_frontend deploy_backend restart_services health_check echo "" log_info "部署完成!" echo "查看日志: ssh ${DEPLOY_USER}@${SERVER} 'docker logs -f x-server-backend-prod'" } # 执行主流程 main