#!/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" # Sudo 密码(如果需要,建议配置无密码 sudo 更安全) # 配置无密码 sudo: 在服务器上运行: echo "username ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/username SUDO_PASSWORD="1231" # 打印带颜色的消息 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_SUDO_PASSWORD="${SUDO_PASSWORD}" ssh ${server} bash << SSH_EOF set -e DEPLOY_PATH="${DEPLOY_PATH}" DEPLOY_NAME="${DEPLOY_NAME}" SUDO_PASSWORD="\${SSH_SUDO_PASSWORD}" # 检查部署目录是否存在 if [ ! -d "\${DEPLOY_PATH}" ]; then echo "错误:部署目录 \${DEPLOY_PATH} 不存在,请检查路径是否正确" exit 1 fi # 检查是否有权限写入(尝试创建测试文件) if ! touch "\${DEPLOY_PATH}/.deploy_test" 2>/dev/null; then echo "提示:没有直接写入权限,将使用 sudo 执行操作" USE_SUDO=1 else rm -f "\${DEPLOY_PATH}/.deploy_test" USE_SUDO=0 fi # 备份旧版本(如果存在) if [ -d "\${DEPLOY_PATH}/\${DEPLOY_NAME}" ]; then echo "备份旧版本..." if [ "\$USE_SUDO" = "1" ]; then echo "\${SUDO_PASSWORD}" | sudo -S rm -rf "\${DEPLOY_PATH}/\${DEPLOY_NAME}_bak" 2>/dev/null || true echo "\${SUDO_PASSWORD}" | sudo -S mv "\${DEPLOY_PATH}/\${DEPLOY_NAME}" "\${DEPLOY_PATH}/\${DEPLOY_NAME}_bak" || { echo "错误:备份失败,权限不足"; exit 1; } else rm -rf "\${DEPLOY_PATH}/\${DEPLOY_NAME}_bak" 2>/dev/null || true mv "\${DEPLOY_PATH}/\${DEPLOY_NAME}" "\${DEPLOY_PATH}/\${DEPLOY_NAME}_bak" || { echo "错误:备份失败"; exit 1; } fi fi # 移动新版本到部署目录(覆盖现有目录) if [ -d ~/\${DEPLOY_NAME} ]; then echo "移动新版本到部署目录..." if [ "\$USE_SUDO" = "1" ]; then echo "\${SUDO_PASSWORD}" | sudo -S mv ~/\${DEPLOY_NAME} "\${DEPLOY_PATH}/" || { echo "错误:移动文件失败,权限不足"; exit 1; } else mv ~/\${DEPLOY_NAME} "\${DEPLOY_PATH}/" || { echo "错误:移动文件失败"; exit 1; } fi echo "部署完成!" else echo "错误:找不到 ~/\${DEPLOY_NAME} 目录" exit 1 fi # 重新加载 nginx(如果配置了) if command -v nginx &> /dev/null; then echo "重新加载 nginx..." echo "\${SUDO_PASSWORD}" | sudo -S nginx -t && echo "\${SUDO_PASSWORD}" | sudo -S nginx -s reload || echo "警告:nginx 重新加载失败,请手动检查" 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