#!/bin/bash # 前端一键部署脚本 # 服务器配置 SERVER_HOST="39.108.66.84" SERVER_USER="root" SERVER_PASSWORD='Kola123!@#' SERVER="$SERVER_USER@$SERVER_HOST" SERVER_PATH="/www/wwwroot/leaser_front" DIST_DIR="dist" FRONTEND_PORT="9501" # 默认端口,宝塔面板站点推荐使用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}[信息]${NC} $1"; } success() { echo -e "${GREEN}[成功]${NC} $1"; } error() { echo -e "${RED}[错误]${NC} $1"; } warn() { echo -e "${YELLOW}[警告]${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 } # 检查前端的端口配置 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 || echo 'No port info found'") # 第二种方法:如果宝塔面板有站点配置表 if [ "$port_info" = "No port info found" ]; then port_info=$(run_ssh "if [ -f /www/server/panel/data/site.json ]; then cat /www/server/panel/data/site.json | grep -E '\"name\":\"leaser_front|\"port\":' | head -2; else echo 'No site config found'; fi") fi if [[ $port_info =~ listen[[:space:]]+([0-9]+) ]] || [[ $port_info =~ \"port\":\"?([0-9]+)\"? ]]; then FRONTEND_PORT=${BASH_REMATCH[1]} success "宝塔面板检测到前端站点端口: $FRONTEND_PORT" else warn "未在宝塔面板中找到前端站点配置,将使用默认端口: $FRONTEND_PORT" warn "建议在宝塔面板创建一个新站点,站点目录为: $SERVER_PATH" fi } echo "========================================" log "前端项目远程部署工具" echo "服务器: $SERVER" echo "项目路径: $SERVER_PATH" echo "========================================" show_password_hint echo "" # 远程构建函数 remote_build() { log "在服务器上进行构建..." run_ssh "cd $SERVER_PATH && \ echo '检查Node环境和依赖...' && \ node -v && npm -v && \ echo '检查并安装 pnpm...' && \ if ! command -v pnpm &>/dev/null; then \ echo '安装 pnpm...' && \ npm install -g pnpm; \ else \ echo 'pnpm已安装: ' && pnpm -v; \ fi && \ echo '安装项目依赖...' && \ pnpm install && \ echo '开始构建项目...' && \ NODE_ENV=production pnpm build && \ if [ -d '$DIST_DIR' ]; then \ echo '✅ 远程构建成功'; \ if [ -d 'backup_dist' ]; then rm -rf backup_dist; fi && \ mkdir -p backup_dist && \ find . -maxdepth 1 -not -path './node_modules*' -not -path './.git*' -not -path './$DIST_DIR*' -not -path './backup_dist*' -not -path '.' | xargs -I{} mv {} backup_dist/ 2>/dev/null || true && \ mv $DIST_DIR/* . && \ rmdir $DIST_DIR && \ echo '✅ 部署文件就位完成'; \ else \ echo '❌ 远程构建失败'; \ exit 1; \ fi" if [ $? -eq 0 ]; then success "远程构建并部署成功" return 0 else error "远程构建失败" return 1 fi } case "${1:-deploy}" in "test"|"t") log "测试服务器连接..." run_ssh "echo '✅ 连接成功'" ;; "status"|"s") log "查看前端项目状态..." run_ssh "cd $SERVER_PATH && echo '=== 文件统计 ===' && find . -type f -not -path '*/\.*' | grep -v 'node_modules' | wc -l && echo '=== 最新文件 ===' && find . -type f -not -path '*/\.*' | grep -v 'node_modules' | xargs ls -lt | head -5 && echo '=== Nginx状态 ===' && systemctl status nginx | grep Active || echo 'Nginx可能未安装'" ;; "logs"|"l") log "查看Nginx访问日志..." run_ssh "tail -f /var/log/nginx/access.log 2>/dev/null || echo '无法访问Nginx日志'" ;; "check"|"c") log "检查前端部署情况..." run_ssh "cd $SERVER_PATH && echo '=== 目录内容 ===' && ls -la | grep -v node_modules && echo '=== 文件大小 ===' && du -sh && echo '=== index.html检查 ===' && cat index.html 2>/dev/null | grep -i title | head -1 || echo '找不到index.html文件'" ;; "nginx") log "检查Nginx配置..." run_ssh "cat /etc/nginx/sites-enabled/* 2>/dev/null || cat /etc/nginx/conf.d/* 2>/dev/null || cat /www/server/nginx/conf/nginx.conf 2>/dev/null || echo '找不到Nginx配置'" ;; "portconfig") log "查询宝塔面板前端站点配置..." run_ssh "echo '=== 宝塔站点配置文件 ===' && \ find /www/server/panel/vhost/nginx/ -name '*.conf' -exec ls -la {} \; 2>/dev/null && \ echo '=== 宝塔站点配置查询 ===' && \ grep -r 'leaser_front' /www/server/panel/vhost/nginx/ 2>/dev/null || echo '未在Nginx配置中找到前端站点配置' && \ echo '=== 宝塔站点列表 ===' && \ if [ -f /www/server/panel/data/site.json ]; then grep -E '\"name|\"path|\"port' /www/server/panel/data/site.json | head -15; else echo '未找到宝塔站点数据'; fi" check_frontend_port ;; "build"|"b") clean_local_build local_build ;; "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://||'))" ;; "upload"|"u") if [ -d "$DIST_DIR" ]; then upload_files else error "未找到 $DIST_DIR 目录,请先执行构建命令" fi ;; "deploy"|"d"|"") log "开始前端远程部署流程..." echo "" log "步骤 1/3: 拉取最新代码" run_ssh "cd $SERVER_PATH && git pull || echo '拉取代码失败,请检查服务器Git配置'" log "步骤 2/3: 备份现有文件" run_ssh "cd $SERVER_PATH && mkdir -p backup_$(date +%Y%m%d) && find . -maxdepth 1 -type f -not -path '*/\.git*' -not -path '*/node_modules*' -exec cp {} backup_$(date +%Y%m%d)/ \; 2>/dev/null || echo '没有需要备份的文件'" log "步骤 3/3: 远程构建部署" if remote_build; then # 检查端口配置 check_frontend_port success "🎉 部署流程完成!" if [ "$FRONTEND_PORT" = "80" ]; then echo "🌐 网站地址: http://$SERVER_HOST" else echo "🌐 网站地址: http://$SERVER_HOST:$FRONTEND_PORT" fi echo "📡 如果还没有在宝塔面板创建站点,请在宝塔面板中创建一个新站点,指向路径 $SERVER_PATH" echo "" log "执行状态检查..." run_ssh "cd $SERVER_PATH && echo '=== 文件检查 ===' && ls -la | grep -v node_modules | head -10 && echo '=== index.html存在检查 ===' && [ -f index.html ] && echo '✅ index.html 存在' || echo '❌ index.html 不存在'" else error "部署失败" exit 1 fi ;; "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 " pull/p 仅拉取远程代码" echo " upload/u 仅上传构建文件" echo " help/h 显示帮助" ;; *) error "未知命令: $1" echo "使用 'help' 查看可用命令" exit 1 ;; esac