#!/bin/bash # Document AI Frontend 部署脚本 # 功能:构建项目并部署到 ubuntu 服务器 set -e # 遇到错误立即退出 # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # 服务器配置 ubuntu_HOST="ubuntu" DEPLOY_PATH="/var/www" DEPLOY_NAME="app.cloud" # 打印带颜色的消息 print_info() { echo -e "${BLUE}[INFO]${NC} $1" } print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } print_error() { echo -e "${RED}[ERROR]${NC} $1" } # 检查命令是否存在 check_command() { if ! command -v $1 &> /dev/null; then print_error "$1 命令未找到,请先安装" exit 1 fi } # 部署到服务器 deploy_to_server() { local server=$1 print_info "开始部署到 ${server}..." # 上传构建产物(app.cloud 目录) print_info "上传 ${DEPLOY_NAME} 目录到 ${server}..." scp_output=$(scp -r ${DEPLOY_NAME} ${server}:~ 2>&1) scp_exit_code=$? if [ $scp_exit_code -eq 0 ]; then print_success "文件上传成功" else print_error "文件上传失败,请检查 SSH 连接和权限" echo "$scp_output" | sed 's/^/ /' return 1 fi # SSH 执行部署操作(非交互模式) print_info "在 ${server} 上执行部署操作..." print_info "部署路径: ${DEPLOY_PATH}/${DEPLOY_NAME}" ssh_output=$(ssh ${server} bash << SSH_EOF set -e DEPLOY_PATH="${DEPLOY_PATH}" DEPLOY_NAME="${DEPLOY_NAME}" # 检查部署目录是否存在 if [ ! -d "\${DEPLOY_PATH}" ]; then echo "错误:部署目录 \${DEPLOY_PATH} 不存在,请检查路径是否正确" exit 1 fi # 检查是否有权限写入,若无则尝试免密 sudo(sudo -n) SUDO_CMD="" if ! touch "\${DEPLOY_PATH}/.deploy_test" 2>/dev/null; then if sudo -n true 2>/dev/null; then echo "提示:没有直接写入权限,使用 sudo -n 执行部署操作" SUDO_CMD="sudo -n" else echo "错误:没有写入权限,且 sudo 需要密码(非交互部署无法输入)" echo "请执行以下任一方案后重试:" echo " 1) 将部署目录改为当前用户可写目录(例如 /home/\$USER/www)" echo " 2) 为当前用户配置免密 sudo(NOPASSWD)" exit 1 fi else rm -f "\${DEPLOY_PATH}/.deploy_test" echo "提示:检测到部署目录可直接写入" fi # 备份旧版本(如果存在) if [ -d "\${DEPLOY_PATH}/\${DEPLOY_NAME}" ]; then echo "备份旧版本..." \$SUDO_CMD rm -rf "\${DEPLOY_PATH}/\${DEPLOY_NAME}_bak" 2>/dev/null || true \$SUDO_CMD mv "\${DEPLOY_PATH}/\${DEPLOY_NAME}" "\${DEPLOY_PATH}/\${DEPLOY_NAME}_bak" || { echo "错误:备份失败,权限不足"; exit 1; } fi # 移动新版本到部署目录(覆盖现有目录) if [ -d ~/\${DEPLOY_NAME} ]; then echo "移动新版本到部署目录..." \$SUDO_CMD mv ~/\${DEPLOY_NAME} "\${DEPLOY_PATH}/" || { echo "错误:移动文件失败,权限不足"; exit 1; } echo "部署完成!" else echo "错误:找不到 ~/\${DEPLOY_NAME} 目录" exit 1 fi # 重新加载 nginx(如果配置了) if command -v nginx &> /dev/null; then echo "重新加载 nginx..." if [ -n "\$SUDO_CMD" ]; then \$SUDO_CMD nginx -t && \$SUDO_CMD nginx -s reload || echo "警告:nginx 重新加载失败,请手动检查" else nginx -t && nginx -s reload || echo "警告:nginx 重新加载失败,请手动检查" fi fi SSH_EOF ) ssh_exit_code=$? # 显示 SSH 输出 if [ -n "$ssh_output" ]; then echo "$ssh_output" | sed 's/^/ /' fi if [ $ssh_exit_code -eq 0 ]; then print_success "${server} 部署成功!" else print_error "${server} 部署失败!" print_error "请检查:" print_error " 1. SSH 连接是否正常" print_error " 2. 部署目录 ${DEPLOY_PATH} 是否存在" print_error " 3. 是否有 sudo 权限(如果需要)" print_error " 4. 上传的文件 ~/${DEPLOY_NAME} 是否存在" return 1 fi } # 主函数 main() { print_info "==========================================" print_info "Document AI Frontend 部署脚本" print_info "==========================================" echo "" # 检查必要的命令 print_info "检查环境..." check_command "npm" check_command "scp" check_command "ssh" # 步骤1: 构建项目 print_info "步骤 1/2: 构建项目(测试环境)..." if npm run build:dev; then print_success "构建完成!" else print_error "构建失败!" exit 1 fi echo "" # 检查 dist 目录是否存在 if [ ! -d "dist" ]; then print_error "dist 目录不存在,构建可能失败" exit 1 fi # 重命名 dist 为 app.cloud print_info "重命名 dist 为 ${DEPLOY_NAME}..." if [ -d "${DEPLOY_NAME}" ]; then rm -rf "${DEPLOY_NAME}" fi mv dist "${DEPLOY_NAME}" print_success "重命名完成" echo "" # 步骤2: 部署到 ubuntu print_info "步骤 2/2: 部署到 ubuntu..." if deploy_to_server ${ubuntu_HOST}; then print_success "ubuntu 部署完成" else print_error "ubuntu 部署失败" exit 1 fi echo "" # 完成 print_info "清理临时文件..." # 可以选择是否删除本地的 app.cloud 目录 # rm -rf ${DEPLOY_NAME} print_success "==========================================" print_success "部署完成!" print_success "==========================================" } # 运行主函数 main