5f110b6988
更新内容: - DEPLOY_ONLINE_GUIDE.md: 详细说明前端本地打包的优势和流程 - deploy-1panel.sh: 优化部署脚本,添加前端构建验证 - 强调前后端分离部署的架构差异 核心变更: 1. 明确说明前端必须本地打包(npm run build) 2. 上传的是打包后的静态文件,不需要服务器 Node.js 3. 添加前端构建验证步骤 4. 优化部署流程提示和输出 部署流程: - 本地:前端构建 → 验证构建 → 上传静态文件 - 服务器:后端代码 → Docker 容器运行 - 1Panel:Nginx 托管静态文件 + 反向代理后端 API Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
232 lines
5.7 KiB
Bash
Executable File
232 lines
5.7 KiB
Bash
Executable File
#!/bin/bash
|
|
# uniservice-mobile.hnxinyouhe.com 部署脚本
|
|
# 使用方法: ./deploy-1panel.sh [server]
|
|
|
|
set -e
|
|
|
|
# ============================================
|
|
# 配置
|
|
# ============================================
|
|
SERVER=${1:-"your-server-ip"}
|
|
DEPLOY_USER="root"
|
|
FRONTEND_BUILD_DIR="./frontend/dist"
|
|
BACKEND_SOURCE_DIR="./backend"
|
|
|
|
# 1Panel 网站目录
|
|
REMOTE_ROOT="/www/sites/uniservice-mobile.hnxinyouhe.com/index"
|
|
|
|
# 后端部署目录
|
|
REMOTE_BACKEND_DIR="/opt/x-server-mobile/backend"
|
|
|
|
# 颜色输出
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
log_info() {
|
|
echo -e "${GREEN}[INFO]${NC} $1"
|
|
}
|
|
|
|
log_warn() {
|
|
echo -e "${YELLOW}[WARN]${NC} $1"
|
|
}
|
|
|
|
log_error() {
|
|
echo -e "${RED}[ERROR]${NC} $1"
|
|
}
|
|
|
|
log_step() {
|
|
echo -e "${BLUE}==>${NC} $1"
|
|
}
|
|
|
|
# ============================================
|
|
# 检查环境
|
|
# ============================================
|
|
check_env() {
|
|
log_step "检查部署环境..."
|
|
|
|
if ! command -v rsync &> /dev/null; then
|
|
log_error "rsync 未安装,请先安装: apt-get install rsync"
|
|
log_info "macOS: brew install rsync"
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -d "$FRONTEND_BUILD_DIR" ]; then
|
|
log_error "❌ 前端构建目录不存在: $FRONTEND_BUILD_DIR"
|
|
echo ""
|
|
log_info "请先在本地构建前端:"
|
|
echo " cd frontend"
|
|
echo " npm install"
|
|
echo " npm run build"
|
|
echo ""
|
|
exit 1
|
|
fi
|
|
|
|
log_info "✓ 环境检查通过"
|
|
}
|
|
|
|
# ============================================
|
|
# 验证前端构建
|
|
# ============================================
|
|
verify_frontend() {
|
|
log_step "验证前端构建..."
|
|
|
|
if [ ! -f "$FRONTEND_BUILD_DIR/index.html" ]; then
|
|
log_error "❌ 前端构建不完整,缺少 index.html"
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -d "$FRONTEND_BUILD_DIR/assets" ]; then
|
|
log_warn "⚠️ 未找到 assets 目录,可能是构建失败"
|
|
fi
|
|
|
|
log_info "✓ 前端构建验证通过"
|
|
echo " - index.html: 存在"
|
|
echo " - 构建时间: $(ls -lt $FRONTEND_BUILD_DIR/index.html | head -1 | awk '{print $6, $7, $8}')"
|
|
}
|
|
|
|
# ============================================
|
|
# 部署前端(上传静态文件)
|
|
# ============================================
|
|
deploy_frontend() {
|
|
log_step "部署前端静态文件..."
|
|
|
|
echo " 本地: $FRONTEND_BUILD_DIR/"
|
|
echo " 远程: ${DEPLOY_USER}@${SERVER}:${REMOTE_ROOT}/"
|
|
|
|
rsync -avz --delete \
|
|
--exclude='*.map' \
|
|
--progress \
|
|
${FRONTEND_BUILD_DIR}/ \
|
|
${DEPLOY_USER}@${SERVER}:${REMOTE_ROOT}/
|
|
|
|
log_info "✓ 前端部署完成"
|
|
}
|
|
|
|
# ============================================
|
|
# 部署后端
|
|
# ============================================
|
|
deploy_backend() {
|
|
log_step "部署后端代码..."
|
|
|
|
# 创建后端目录(如果不存在)
|
|
ssh ${DEPLOY_USER}@${SERVER} "mkdir -p ${REMOTE_BACKEND_DIR}"
|
|
|
|
echo " 本地: $BACKEND_SOURCE_DIR/"
|
|
echo " 远程: ${DEPLOY_USER}@${SERVER}:${REMOTE_BACKEND_DIR}/"
|
|
|
|
rsync -avz \
|
|
--exclude='vendor' \
|
|
--exclude='runtime' \
|
|
--exclude='.git' \
|
|
--exclude='node_modules' \
|
|
--exclude='.idea' \
|
|
--progress \
|
|
${BACKEND_SOURCE_DIR}/ \
|
|
${DEPLOY_USER}@${SERVER}:${REMOTE_BACKEND_DIR}/
|
|
|
|
log_info "✓ 后端部署完成"
|
|
}
|
|
|
|
# ============================================
|
|
# 重启后端容器
|
|
# ============================================
|
|
restart_backend() {
|
|
log_step "重启后端容器..."
|
|
|
|
ssh ${DEPLOY_USER}@${SERVER} << 'EOF'
|
|
echo "正在检查后端目录..."
|
|
cd /opt/x-server-mobile
|
|
|
|
if [ ! -f "deploy/docker-compose.prod.yml" ]; then
|
|
echo "❌ docker-compose.prod.yml 不存在"
|
|
echo " 请先上传部署配置文件"
|
|
exit 1
|
|
fi
|
|
|
|
echo "停止旧容器..."
|
|
docker-compose -f deploy/docker-compose.prod.yml down 2>/dev/null || true
|
|
|
|
echo "启动新容器..."
|
|
docker-compose -f deploy/docker-compose.prod.yml up -d
|
|
|
|
echo ""
|
|
echo "容器状态:"
|
|
docker ps | grep x-server
|
|
|
|
echo ""
|
|
echo "✓ 后端容器重启完成"
|
|
EOF
|
|
|
|
if [ $? -eq 0 ]; then
|
|
log_info "✓ 后端容器重启成功"
|
|
else
|
|
log_error "✗ 后端容器重启失败"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# ============================================
|
|
# 显示部署信息
|
|
# ============================================
|
|
show_deployment_info() {
|
|
echo ""
|
|
log_step "部署信息"
|
|
echo ""
|
|
echo "🌐 访问地址: https://uniservice-mobile.hnxinyouhe.com"
|
|
echo ""
|
|
echo "📁 前端目录: ${REMOTE_ROOT}"
|
|
echo "📁 后端目录: ${REMOTE_BACKEND_DIR}"
|
|
echo ""
|
|
echo "📊 后端容器: x-server-backend-prod (端口 8787)"
|
|
echo ""
|
|
}
|
|
|
|
# ============================================
|
|
# 主流程
|
|
# ============================================
|
|
main() {
|
|
echo "=========================================="
|
|
echo " uniservice-mobile 部署脚本"
|
|
echo "=========================================="
|
|
echo ""
|
|
echo "📍 目标服务器: ${SERVER}"
|
|
echo ""
|
|
|
|
# 检查环境
|
|
check_env
|
|
|
|
# 验证前端构建
|
|
verify_frontend
|
|
|
|
echo ""
|
|
read -p "是否继续部署? (y/N): " confirm
|
|
if [[ ! $confirm =~ ^[Yy]$ ]]; then
|
|
log_warn "部署已取消"
|
|
exit 0
|
|
fi
|
|
|
|
echo ""
|
|
|
|
# 部署前端
|
|
deploy_frontend
|
|
|
|
echo ""
|
|
read -p "是否需要部署后端? (y/N): " deploy_backend_choice
|
|
if [[ $deploy_backend_choice =~ ^[Yy]$ ]]; then
|
|
echo ""
|
|
deploy_backend
|
|
restart_backend
|
|
else
|
|
log_info "跳过后端部署"
|
|
fi
|
|
|
|
echo ""
|
|
show_deployment_info
|
|
}
|
|
|
|
# 执行主流程
|
|
main "$@"
|