#!/bin/bash # 前端远程部署脚本 - 本地构建版本 # 本地构建,远程部署,避免服务器环境依赖 # 服务器配置 SERVER_HOST="120.79.214.48" SERVER_USER="root" SERVER_PASSWORD='Kola123!@#' SERVER="$SERVER_USER@$SERVER_HOST" SERVER_PATH="/www/wwwroot/leaser_front" DIST_DIR="dist" FRONTEND_PORT="9501" # 检测是否安装了sshpass if command -v sshpass >/dev/null 2>&1; then USE_SSHPASS=true SSH_CMD="sshpass -p $SERVER_PASSWORD ssh -o StrictHostKeyChecking=no" SCP_CMD="sshpass -p $SERVER_PASSWORD scp -o StrictHostKeyChecking=no -r" else USE_SSHPASS=false SSH_CMD="ssh -o StrictHostKeyChecking=no" SCP_CMD="scp -o StrictHostKeyChecking=no -r" fi # 颜色定义 GREEN='\033[0;32m' BLUE='\033[0;34m' RED='\033[0;31m' YELLOW='\033[1;33m' NC='\033[0m' log() { echo -e "${BLUE}[INFO]${NC} $1"; } success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; } error() { echo -e "${RED}[ERROR]${NC} $1"; } warn() { echo -e "${YELLOW}[WARNING]${NC} $1"; } # SSH执行函数 run_ssh() { local cmd="$1" if [ "$USE_SSHPASS" = true ]; then $SSH_CMD "$SERVER" "$cmd" else echo -e "${YELLOW}[SSH连接]${NC} 请输入服务器密码: $SERVER_PASSWORD" $SSH_CMD "$SERVER" "$cmd" fi } # SCP上传函数 run_scp() { local source="$1" local dest="$2" if [ "$USE_SSHPASS" = true ]; then $SCP_CMD "$source" "$SERVER:$dest" else echo -e "${YELLOW}[SCP上传]${NC} 请输入服务器密码: $SERVER_PASSWORD" $SCP_CMD "$source" "$SERVER:$dest" fi } # 显示密码提示 show_password_hint() { if [ "$USE_SSHPASS" = true ]; then echo -e "${GREEN}[sshpass]${NC} 已启用自动登录,无需手动输入密码 ✅" else echo -e "${YELLOW}[密码提示]${NC} 服务器密码: $SERVER_PASSWORD" echo -e "${BLUE}[建议]${NC} 安装 sshpass 以启用自动登录" echo " Mac: brew install hudochenkov/sshpass/sshpass" echo " Ubuntu/Debian: apt-get install sshpass" echo " CentOS/RHEL: yum install sshpass" fi } # 本地构建 local_build() { log "本地构建项目..." # 检查本地环境 if ! command -v node >/dev/null 2>&1; then error "本地未安装 Node.js,请先安装" return 1 fi if ! command -v pnpm >/dev/null 2>&1; then warn "本地未安装 pnpm,尝试安装..." npm install -g pnpm || { error "pnpm 安装失败" return 1 } fi log "Node版本: $(node -v)" log "pnpm版本: $(pnpm -v)" # 清理本地构建目录 if [ -d "$DIST_DIR" ]; then log "清理本地构建目录..." rm -rf "$DIST_DIR" fi # 安装依赖 log "安装项目依赖..." pnpm install || { error "依赖安装失败" return 1 } # 构建项目 log "开始构建..." NODE_ENV=production pnpm build || { error "构建失败" return 1 } # 检查构建结果 if [ -d "$DIST_DIR" ] && [ "$(ls -A $DIST_DIR 2>/dev/null)" ]; then success "✅ 本地构建成功" log "构建文件数量: $(find $DIST_DIR -type f | wc -l)" return 0 else error "构建目录为空或不存在" return 1 fi } # 上传构建文件 upload_files() { log "上传构建文件到服务器..." if [ ! -d "$DIST_DIR" ]; then error "本地构建目录不存在,请先执行构建" return 1 fi # 确保服务器dist目录存在并清理 run_ssh "mkdir -p $SERVER_PATH/$DIST_DIR && rm -rf $SERVER_PATH/$DIST_DIR/* 2>/dev/null || true" # 上传到目标目录 run_scp "$DIST_DIR/" "$SERVER_PATH/$DIST_DIR/" if [ $? -eq 0 ]; then success "✅ 文件上传成功" return 0 else error "文件上传失败" return 1 fi } # 检查部署结果 verify_deployment() { log "检查部署结果..." run_ssh "cd $SERVER_PATH/$DIST_DIR && if [ -f index.html ]; then echo '✅ index.html 部署成功'; file_count=\$(find . -type f -not -path '*/\.*' | wc -l); echo \"✅ 共部署 \$file_count 个文件\"; else echo '❌ 部署验证失败'; exit 1; fi" } # 检查前端端口配置 check_frontend_port() { log "检查前端站点配置..." local port_info=$(run_ssh "grep -r 'leaser_front' /www/server/panel/vhost/nginx/ 2>/dev/null | grep -i listen | head -1" 2>/dev/null || echo "") if [[ $port_info =~ listen[[:space:]]+([0-9]+) ]]; then FRONTEND_PORT=${BASH_REMATCH[1]} success "检测到前端站点端口: $FRONTEND_PORT" else warn "未找到宝塔面板站点配置,使用默认端口: $FRONTEND_PORT" warn "请在宝塔面板创建站点,目录指向: $SERVER_PATH/$DIST_DIR" fi } echo "========================================" log "前端远程部署工具 - 本地构建版本" echo "服务器: $SERVER" echo "项目路径: $SERVER_PATH" echo "本地目录: $(pwd)" echo "========================================" show_password_hint echo "" case "${1:-deploy}" in "test"|"t") log "测试服务器连接..." run_ssh "echo '✅ 连接成功' && echo '服务器信息:' && uname -a" ;; "status"|"s") log "查看前端项目状态..." run_ssh "cd $SERVER_PATH/$DIST_DIR && echo '=== 目录信息 ===' && pwd && ls -la | head -10 && echo '=== 文件统计 ===' && find . -type f -not -path '*/\.*' -not -path '*/node_modules*' | wc -l && echo '个文件' && echo '=== 最新文件 ===' && find . -maxdepth 1 -type f -not -path '*/\.*' | head -5 | xargs ls -la 2>/dev/null || echo '无文件'" ;; "logs"|"l") log "查看Nginx访问日志..." run_ssh "tail -20 /var/log/nginx/access.log 2>/dev/null || tail -20 /www/wwwlogs/access.log 2>/dev/null || echo '找不到Nginx访问日志'" ;; "check"|"c") log "检查前端部署情况..." run_ssh "cd $SERVER_PATH/$DIST_DIR && echo '=== 关键文件检查 ===' && [ -f index.html ] && echo '✅ index.html 存在' || echo '❌ index.html 不存在' && echo '=== 静态资源检查 ===' && ls -la *.js *.css 2>/dev/null | head -3 || echo '无JS/CSS文件' && echo '=== 目录大小 ===' && du -sh . 2>/dev/null || echo '无法获取大小'" ;; "nginx") log "检查Nginx配置..." run_ssh "nginx -t 2>/dev/null && echo '✅ Nginx配置正确' || echo '❌ Nginx配置有误'" check_frontend_port ;; "portconfig") check_frontend_port ;; "build"|"b") local_build ;; "upload"|"u") if [ -d "$DIST_DIR" ]; then upload_files else error "未找到 $DIST_DIR 目录,请先执行构建命令" fi ;; "pull"|"p") log "拉取最新代码到服务器..." run_ssh "cd $SERVER_PATH && (git pull 2>/dev/null || git pull https://kola:Cyne2012@\$(git config --get remote.origin.url | sed 's|https://||'))" ;; "deploy"|"d"|"") log "开始前端部署流程..." echo "" log "步骤 1/3: 本地构建" if ! local_build; then error "本地构建失败,部署终止" exit 1 fi log "步骤 2/3: 上传文件" if ! upload_files; then error "文件上传失败,部署终止" exit 1 fi log "步骤 3/3: 检查部署结果" verify_deployment # 检查端口配置 check_frontend_port # 清理本地构建文件 log "清理本地构建文件..." rm -rf "$DIST_DIR" success "🎉 部署完成!" if [ "$FRONTEND_PORT" = "80" ]; then echo "🌐 访问地址: http://$SERVER_HOST" else echo "🌐 访问地址: http://$SERVER_HOST:$FRONTEND_PORT" fi echo "" warn "如果网站无法访问,请检查:" echo " 1. 在宝塔面板中创建站点,目录指向: $SERVER_PATH" echo " 2. 确保防火墙开放端口: $FRONTEND_PORT" echo " 3. 检查域名解析是否正确" ;; "help"|"h"|"--help") echo "前端远程部署工具 - 本地构建版本" echo "" echo "用法: $0 [命令]" echo "" echo "命令:" echo " deploy/d 完整部署流程(默认)" echo " test/t 测试服务器连接" echo " status/s 查看项目状态" echo " check/c 检查部署情况" echo " logs/l 查看Nginx日志" echo " nginx 检查Nginx配置" echo " portconfig 检查端口配置" echo " build/b 仅本地构建" echo " upload/u 仅上传构建文件" echo " pull/p 拉取代码到服务器" echo " help/h 显示帮助" ;; *) error "未知命令: $1" echo "使用 '$0 help' 查看可用命令" exit 1 ;; esac