1、步骤

  1. 拉取代码,npm根据环境打包。
  2. 删除nginx下旧版项目,将生成的新版文件复制到nginx下。

2、脚本

#!/bin/bash

# 设置颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# 配置参数 - 请根据实际情况修改
PROJECT_NAME="my-frontend-project"
GIT_REPO="git@github.com:username/my-frontend-project.git"
PROJECT_DIR="/home/user/projects/$PROJECT_NAME"
NGINX_ROOT="/usr/share/nginx/html"
BACKUP_DIR="/home/user/backups"
LOG_FILE="/var/log/deploy_$PROJECT_NAME.log"

# 获取部署环境,默认为prod
ENV=${1:-prod}

# 日志函数
log() {
    echo -e "[$(date +'%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOG_FILE
}

# 成功日志
log_success() {
    echo -e "[$(date +'%Y-%m-%d %H:%M:%S')] ${GREEN}✓ $1${NC}" | tee -a $LOG_FILE
}

# 错误日志
log_error() {
    echo -e "[$(date +'%Y-%m-%d %H:%M:%S')] ${RED}✗ $1${NC}" | tee -a $LOG_FILE
}

# 警告日志
log_warning() {
    echo -e "[$(date +'%Y-%m-%d %H:%M:%S')] ${YELLOW}! $1${NC}" | tee -a $LOG_FILE
}

# 错误处理函数
handle_error() {
    log_error "部署失败: $1"
    exit 1
}

# 检查命令是否存在
check_command() {
    if ! command -v $1 &> /dev/null; then
        handle_error "$1 命令未找到,请先安装"
    fi
}

# 检查必要目录
check_directories() {
    mkdir -p $PROJECT_DIR || handle_error "无法创建项目目录"
    mkdir -p $BACKUP_DIR || handle_error "无法创建备份目录"
    mkdir -p $(dirname $LOG_FILE) || log_warning "无法创建日志目录"
}

# 主函数
main() {
    log "========================================="
    log "开始前端部署脚本"
    log "项目: $PROJECT_NAME"
    log "环境: $ENV"
    log "时间: $(date)"
    log "========================================="

    # 检查必要命令
    check_command "git"
    check_command "npm"
    check_command "node"

    # 检查必要目录
    check_directories

    # 第一步:拉取代码
    log "第一步:拉取代码..."
    cd $PROJECT_DIR || handle_error "无法进入项目目录"

    if [ -d ".git" ]; then
        log "项目已存在,拉取最新代码..."
        git fetch --all || handle_error "Git fetch 失败"
        git reset --hard origin/main || handle_error "Git reset 失败"
        log_success "代码更新成功"
    else
        log "首次部署,克隆代码..."
        git clone $GIT_REPO . || handle_error "Git clone 失败"
        log_success "代码克隆成功"
    fi

    # 检查当前分支
    CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
    log "当前分支: $CURRENT_BRANCH"

    # 第二步:安装依赖
    log "第二步:安装依赖..."
    npm install || handle_error "npm install 失败"
    log_success "依赖安装成功"

    # 第三步:打包项目
    log "第三步:打包项目..."

    # 根据环境选择打包命令
    case $ENV in
        prod)
            BUILD_COMMAND="build:prod"
            ;;
        test)
            BUILD_COMMAND="build:test"
            ;;
        dev)
            BUILD_COMMAND="build:dev"
            ;;
        *)
            BUILD_COMMAND="build"
            ;;
    esac

    # 检查package.json中是否有对应的脚本
    if ! grep -q "\"$BUILD_COMMAND\"" package.json; then
        log_warning "未找到 $BUILD_COMMAND 脚本,使用默认 build 脚本"
        BUILD_COMMAND="build"
    fi

    npm run $BUILD_COMMAND || handle_error "打包失败"
    log_success "打包成功"

    # 检查dist目录是否存在
    if [ ! -d "dist" ]; then
        handle_error "dist 目录不存在,打包可能失败"
    fi

    # 第四步:备份当前版本
    log "第四步:备份当前版本..."
    if [ -d "$NGINX_ROOT/$PROJECT_NAME" ]; then
        BACKUP_TIME=$(date +"%Y%m%d_%H%M%S")
        BACKUP_FILE="$BACKUP_DIR/${PROJECT_NAME}_${ENV}_${BACKUP_TIME}.tar.gz"
        
        tar -czf $BACKUP_FILE -C $NGINX_ROOT $PROJECT_NAME 2>/dev/null
        
        if [ $? -eq 0 ] && [ -f $BACKUP_FILE ]; then
            log_success "备份成功: $(basename $BACKUP_FILE)"
            
            # 清理旧备份(保留最近5个)
            cd $BACKUP_DIR
            ls -t ${PROJECT_NAME}_${ENV}_*.tar.gz 2>/dev/null | tail -n +6 | xargs -r rm
            log "清理旧备份完成,保留最近5个备份"
        else
            log_warning "备份失败,继续部署..."
        fi
    else
        log "没有找到旧版本,无需备份"
    fi

    # 第五步:部署到Nginx
    log "第五步:部署到Nginx..."

    # 删除旧版本
    if [ -d "$NGINX_ROOT/$PROJECT_NAME" ]; then
        rm -rf "$NGINX_ROOT/$PROJECT_NAME" || handle_error "删除旧版本失败"
        log "已删除旧版本"
    fi

    # 复制新版本
    cp -r "$PROJECT_DIR/dist" "$NGINX_ROOT/$PROJECT_NAME" || handle_error "复制新版本失败"
    log_success "新版本复制成功"

    # 设置权限
    chmod -R 755 "$NGINX_ROOT/$PROJECT_NAME" || log_warning "权限设置失败"
    
    # 检查Nginx配置
    log "检查Nginx配置..."
    if command -v nginx &> /dev/null; then
        nginx -t 2>/dev/null
        if [ $? -eq 0 ]; then
            log_success "Nginx配置检查通过"
            
            # 重新加载Nginx
            systemctl reload nginx 2>/dev/null || service nginx reload 2>/dev/null
            if [ $? -eq 0 ]; then
                log_success "Nginx重新加载成功"
            else
                log_warning "Nginx重新加载失败,可能需要手动重启"
            fi
        else
            log_error "Nginx配置检查失败"
        fi
    else
        log_warning "未找到Nginx命令,跳过配置检查"
    fi

    # 部署完成
    log "========================================="
    log_success "部署完成!"
    log "项目: $PROJECT_NAME"
    log "环境: $ENV"
    log "部署时间: $(date)"
    log "部署目录: $NGINX_ROOT/$PROJECT_NAME"
    log "========================================="

    # 显示部署信息
    echo ""
    echo "部署信息:"
    echo "  项目名称: $PROJECT_NAME"
    echo "  部署环境: $ENV"
    echo "  部署时间: $(date)"
    echo "  访问地址: http://your-domain.com"
    if [ -f "$BACKUP_FILE" ]; then
        echo "  备份文件: $(basename $BACKUP_FILE)"
    fi
    echo ""
}

# 执行主函数
main

# 捕获错误
trap 'handle_error "脚本执行被中断"' INT TERM
  • PROJECT_NAME: 项目名称

  • GIT_REPO: Git仓库地址

  • PROJECT_DIR: 项目存放目录

  • NGINX_ROOT: Nginx根目录

  • BACKUP_DIR: 备份目录

3、使用

# 部署到生产环境
./deploy.sh prod

# 部署到测试环境
./deploy.sh test

# 部署到开发环境
./deploy.sh dev
  • 确保脚本有执行权限:chmod +x deploy.sh

  • 确保Nginx目录有写入权限

  • 根据实际情况修改Git分支(main/master)

  • 确保package.json中有对应的build脚本

  • 建议先在测试环境验证脚本

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐