#!/bin/bash # 发布脚本配置 SERVER_HOST="129.204.155.94" SERVER_USER="root" # 根据实际情况修改用户名 SERVER_PATH="/usr/local/web/pilates-server" PROJECT_NAME="pilates-server" # 定义颜色 GREEN='\033[0;32m' YELLOW='\033[1;33m' RED='\033[0;31m' BLUE='\033[0;34m' NC='\033[0m' # No Color # 打印带颜色的消息 print_message() { echo -e "${GREEN}[INFO] $1${NC}" } print_warning() { echo -e "${YELLOW}[WARN] $1${NC}" } print_error() { echo -e "${RED}[ERROR] $1${NC}" } print_step() { echo -e "${BLUE}[STEP] $1${NC}" } # 检查必要的工具 check_requirements() { print_step "检查部署环境..." # 检查rsync if ! command -v rsync &> /dev/null; then print_error "rsync未安装,请先安装rsync" exit 1 fi # 检查ssh if ! command -v ssh &> /dev/null; then print_error "ssh未安装,请先安装ssh" exit 1 fi print_message "环境检查完成" } # 本地构建 build_project() { print_step "开始本地构建..." # 安装依赖 print_message "安装依赖..." if ! yarn install; then print_error "依赖安装失败" exit 1 fi # 构建项目 print_message "构建项目..." if ! yarn build; then print_error "项目构建失败" exit 1 fi print_message "本地构建完成" } # 创建部署包 create_deployment_package() { print_step "创建部署包..." # 创建临时目录 TEMP_DIR=$(mktemp -d) DEPLOY_DIR="$TEMP_DIR/$PROJECT_NAME" print_message "创建临时目录: $DEPLOY_DIR" mkdir -p "$DEPLOY_DIR" # 复制必要文件 print_message "复制项目文件..." # 复制构建后的文件 cp -r dist "$DEPLOY_DIR/" # 复制配置文件 cp package.json "$DEPLOY_DIR/" cp yarn.lock "$DEPLOY_DIR/" cp ecosystem.config.js "$DEPLOY_DIR/" cp start.sh "$DEPLOY_DIR/" # 复制其他必要文件 if [ -f "SubscriptionKey_K3L2F8HFTS.p8" ]; then cp SubscriptionKey_K3L2F8HFTS.p8 "$DEPLOY_DIR/" fi # 创建日志目录 mkdir -p "$DEPLOY_DIR/logs" print_message "部署包创建完成: $DEPLOY_DIR" echo "$DEPLOY_DIR" } # 部署到服务器 deploy_to_server() { local deploy_dir=$1 print_step "部署到服务器..." # 测试SSH连接 print_message "测试SSH连接..." if ! ssh -o ConnectTimeout=10 "$SERVER_USER@$SERVER_HOST" "echo 'SSH连接成功'"; then print_error "无法连接到服务器 $SERVER_HOST" print_warning "请检查:" print_warning "1. 服务器地址是否正确" print_warning "2. SSH密钥是否配置正确" print_warning "3. 服务器是否可访问" exit 1 fi # 在服务器上创建目录 print_message "在服务器上创建目录..." ssh "$SERVER_USER@$SERVER_HOST" "mkdir -p $SERVER_PATH" # 备份现有部署(如果存在) print_message "备份现有部署..." ssh "$SERVER_USER@$SERVER_HOST" " if [ -d '$SERVER_PATH' ] && [ -f '$SERVER_PATH/package.json' ]; then backup_dir='$SERVER_PATH.backup.$(date +%Y%m%d_%H%M%S)' echo '创建备份目录: '\$backup_dir cp -r '$SERVER_PATH' \$backup_dir echo '备份完成' fi " # 停止现有服务 print_message "停止现有服务..." ssh "$SERVER_USER@$SERVER_HOST" " cd $SERVER_PATH if [ -f 'ecosystem.config.js' ]; then pm2 stop ecosystem.config.js 2>/dev/null || true pm2 delete ecosystem.config.js 2>/dev/null || true fi " # 同步文件到服务器 print_message "同步文件到服务器..." if ! rsync -avz --delete "$deploy_dir/" "$SERVER_USER@$SERVER_HOST:$SERVER_PATH/"; then print_error "文件同步失败" exit 1 fi print_message "文件同步完成" } # 在服务器上启动服务 start_service() { print_step "启动服务..." # 在服务器上执行start.sh print_message "在服务器上执行start.sh..." ssh "$SERVER_USER@$SERVER_HOST" " cd $SERVER_PATH chmod +x start.sh ./start.sh " # 检查服务状态 print_message "检查服务状态..." ssh "$SERVER_USER@$SERVER_HOST" " cd $SERVER_PATH pm2 status " } # 清理临时文件 cleanup() { if [ -n "$TEMP_DIR" ] && [ -d "$TEMP_DIR" ]; then print_message "清理临时文件: $TEMP_DIR" rm -rf "$TEMP_DIR" fi } # 主函数 main() { print_message "开始部署 $PROJECT_NAME 到 $SERVER_HOST" print_message "目标目录: $SERVER_PATH" echo "" # 设置错误处理 trap cleanup EXIT # 执行部署步骤 check_requirements build_project DEPLOY_DIR=$(create_deployment_package) TEMP_DIR=$(dirname "$DEPLOY_DIR") deploy_to_server "$DEPLOY_DIR" start_service print_message "" print_message "🎉 部署成功完成!" print_message "服务器: $SERVER_HOST" print_message "目录: $SERVER_PATH" print_message "" print_message "常用命令:" print_message "查看日志: ssh $SERVER_USER@$SERVER_HOST 'cd $SERVER_PATH && pm2 logs'" print_message "查看状态: ssh $SERVER_USER@$SERVER_HOST 'cd $SERVER_PATH && pm2 status'" print_message "重启服务: ssh $SERVER_USER@$SERVER_HOST 'cd $SERVER_PATH && pm2 restart ecosystem.config.js'" } # 参数处理 case "$1" in --help|-h) echo "用法: $0 [选项]" echo "" echo "选项:" echo " --help, -h 显示帮助信息" echo " --dry-run 仅显示将要执行的操作,不实际执行" echo "" echo "配置:" echo " 服务器: $SERVER_HOST" echo " 用户: $SERVER_USER" echo " 路径: $SERVER_PATH" echo "" echo "注意事项:" echo "1. 确保已配置SSH密钥认证" echo "2. 确保服务器上已安装Node.js、yarn、pm2" echo "3. 确保有足够的权限访问目标目录" exit 0 ;; --dry-run) print_message "这是一个模拟运行,不会实际执行部署操作" print_message "将要执行的操作:" print_message "1. 检查本地环境" print_message "2. 构建项目" print_message "3. 创建部署包" print_message "4. 连接到服务器: $SERVER_HOST" print_message "5. 备份现有部署" print_message "6. 停止现有服务" print_message "7. 同步文件到: $SERVER_PATH" print_message "8. 执行start.sh启动服务" exit 0 ;; *) main ;; esac