From 5f110b6988dc0f64ab139191385e6ddd862bb323 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 27 Feb 2026 18:24:42 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=98=8E=E7=A1=AE=E5=89=8D=E7=AB=AF?= =?UTF-8?q?=E6=9C=AC=E5=9C=B0=E6=89=93=E5=8C=85=E9=83=A8=E7=BD=B2=E6=B5=81?= =?UTF-8?q?=E7=A8=8B=EF=BC=8C=E4=BC=98=E5=8C=96=E9=83=A8=E7=BD=B2=E8=84=9A?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 更新内容: - 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 --- deploy/deploy-1panel.sh | 133 +++++++++++++------ docs/DEPLOY_ONLINE_GUIDE.md | 251 +++++++++++++++++++++++++++--------- 2 files changed, 287 insertions(+), 97 deletions(-) diff --git a/deploy/deploy-1panel.sh b/deploy/deploy-1panel.sh index dcbf68d..3bc40c5 100755 --- a/deploy/deploy-1panel.sh +++ b/deploy/deploy-1panel.sh @@ -1,5 +1,5 @@ #!/bin/bash -# X-Server Mobile 1Panel 静态站点部署脚本 +# uniservice-mobile.hnxinyouhe.com 部署脚本 # 使用方法: ./deploy-1panel.sh [server] set -e @@ -22,6 +22,7 @@ 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() { @@ -36,20 +37,30 @@ log_error() { echo -e "${RED}[ERROR]${NC} $1" } +log_step() { + echo -e "${BLUE}==>${NC} $1" +} + # ============================================ # 检查环境 # ============================================ check_env() { - log_info "检查部署环境..." + 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" - log_info "请先运行: cd frontend && npm install && npm run build" + log_error "❌ 前端构建目录不存在: $FRONTEND_BUILD_DIR" + echo "" + log_info "请先在本地构建前端:" + echo " cd frontend" + echo " npm install" + echo " npm run build" + echo "" exit 1 fi @@ -57,24 +68,37 @@ check_env() { } # ============================================ -# 构建前端 +# 验证前端构建 # ============================================ -build_frontend() { - log_info "构建前端..." - cd frontend - npm run build - cd .. - 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_info "部署前端到 1Panel 静态站点..." + 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}/ @@ -85,15 +109,21 @@ deploy_frontend() { # 部署后端 # ============================================ deploy_backend() { - log_info "部署后端..." + 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}/ @@ -104,22 +134,54 @@ deploy_backend() { # 重启后端容器 # ============================================ restart_backend() { - log_info "重启后端容器..." + log_step "重启后端容器..." ssh ${DEPLOY_USER}@${SERVER} << 'EOF' + echo "正在检查后端目录..." cd /opt/x-server-mobile - # 停止旧容器 - docker-compose -f deploy/docker-compose.prod.yml down + 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 "" } # ============================================ @@ -127,43 +189,42 @@ EOF # ============================================ main() { echo "==========================================" - echo " X-Server Mobile 1Panel 部署脚本" + echo " uniservice-mobile 部署脚本" echo "==========================================" echo "" - echo "目标服务器: ${SERVER}" + echo "📍 目标服务器: ${SERVER}" echo "" # 检查环境 check_env - # 询问是否构建前端 - read -p "是否需要构建前端? (y/N): " build_frontend_choice - if [[ $build_frontend_choice =~ ^[Yy]$ ]]; then - build_frontend + # 验证前端构建 + 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 "" - log_info "==========================================" - log_info "部署完成!" - log_info "==========================================" - echo "" - echo "访问地址: https://uniservice-mobile.hnxinyouhe.com" - echo "" - echo "后续步骤:" - echo "1. 在 1Panel 面板中找到网站配置" - echo "2. 将 deploy/nginx-1panel.conf 的内容添加到 Nginx 配置中" - echo "3. 重载 Nginx 配置" - echo "" + show_deployment_info } # 执行主流程 diff --git a/docs/DEPLOY_ONLINE_GUIDE.md b/docs/DEPLOY_ONLINE_GUIDE.md index 1534f60..0f6a79d 100644 --- a/docs/DEPLOY_ONLINE_GUIDE.md +++ b/docs/DEPLOY_ONLINE_GUIDE.md @@ -13,19 +13,38 @@ --- +## 部署架构说明 + +**重要:前后端分离部署** + +| 组件 | 部署位置 | 部署方式 | +|------|---------|---------| +| **前端** | 1Panel 静态站点 | 本地打包 → 上传静态文件 | +| **后端** | Docker 容器 | 上传代码 → 容器运行 | + +### 为什么前端要本地打包? + +1. **服务器不需要 Node.js** - 只需 Nginx 托管静态文件 +2. **打包速度快** - 本地开发机性能通常更好 +3. **节省服务器资源** - 不占用服务器 CPU/内存编译 +4. **避免环境问题** - 本地打包更稳定可靠 + +--- + ## 部署目录结构 ``` 线上服务器: + /www/sites/uniservice-mobile.hnxinyouhe.com/ -├── index/ ← 前端静态文件 +├── index/ ← 前端静态文件(本地打包后上传) │ ├── index.html │ ├── assets/ │ └── ... ├── log/ ← 访问日志 │ ├── access.log │ └── error.log -└── ssl/ ← SSL 证书 +└── ssl/ ← SSL 证书(1Panel 管理) ├── fullchain.pem └── privkey.pem @@ -47,47 +66,61 @@ ## 快速部署步骤 -### 方式一:使用部署脚本(推荐) +### 第一步:本地打包前端(开发机执行) ```bash -# 1. 构建前端 +# 在开发机本地执行 cd /www/x-server-mobile/frontend + +# 安装依赖(首次或依赖变化时) +npm install + +# 构建生产版本 npm run build -# 2. 执行部署脚本 -./deploy/deploy-1panel.sh your-server-ip - -# 脚本会提示: -# - 是否需要构建前端(已构建则选 N) -# - 是否需要部署后端 -# - 自动重启后端容器 +# 构建完成后,静态文件在 frontend/dist/ 目录 +ls frontend/dist/ +# 输出: index.html, assets/, ... ``` -### 方式二:手动部署 - -#### 1. 前端部署 +### 第二步:上传到服务器 ```bash -# 本地构建 -cd /www/x-server-mobile/frontend -npm run build - -# 上传静态文件到服务器 +# 上传前端静态文件到服务器 rsync -avz --delete frontend/dist/* root@your-server:/www/sites/uniservice-mobile.hnxinyouhe.com/index/ + +# 或使用 scp +scp -r frontend/dist/* root@your-server:/www/sites/uniservice-mobile.hnxinyouhe.com/index/ ``` -#### 2. 后端部署 +### 第三步:上传后端代码 ```bash -# 上传后端代码 +# 上传后端代码到服务器 rsync -avz --exclude='vendor' --exclude='runtime' backend/ root@your-server:/opt/x-server-mobile/backend/ +``` -# 在服务器上启动容器 +### 第四步:配置 1Panel Nginx + +在 1Panel 面板中配置反向代理(详见下方 Nginx 配置章节) + +### 第五步:启动后端容器 + +```bash +# 在服务器上执行 ssh root@your-server cd /opt/x-server-mobile -# 上传 docker-compose 和环境变量文件 -# (从本地复制这些文件) +# 确保配置文件已上传 +ls deploy/docker-compose.prod.yml +ls deploy/.env.production + +# 启动后端容器 +docker-compose -f deploy/docker-compose.prod.yml up -d + +# 查看容器状态 +docker ps | grep x-server +docker logs -f x-server-backend-prod ``` --- @@ -120,7 +153,7 @@ location /api/ { } # ============================================ -# 飞书登录回调 +# 飞书登录回调(必须在 API 之前匹配) # ============================================ location /login { @@ -161,7 +194,7 @@ location /feishu/card/callback { } # ============================================ -# 静态资源缓存 +# 静态资源缓存(可选,提升性能) # ============================================ location ~* \.(js|css|png|jpg|jpeg|gif|webp|svg|ico|woff|woff2|ttf|eot)$ { @@ -174,21 +207,25 @@ location ~* \.(js|css|png|jpg|jpeg|gif|webp|svg|ico|woff|woff2|ttf|eot)$ { ### 配置说明 -| 配置项 | 说明 | -|--------|------| +| 路径 | 说明 | +|------|------| | `/api/*` | 后端 API 接口,代理到 8787 端口 | | `/login/*` | 飞书登录回调,代理到后端 | | `/feishu/card/callback` | 飞书卡片回调,代理到后端 | -| 静态资源 | js/css/images 等,缓存 7 天 | +| 静态资源 | js/css/images 等,缓存 7 天(可选) | | 根路径 `/` | SPA 路由,返回 index.html | +**重要**: +- 反向代理规则要放在 `root` 指令**之前** +- 静态资源缓存规则要放在反向代理之前(优先匹配) + --- ## 环境变量配置 -已创建的文件:`deploy/.env.production` +### 飞书配置(必须配置) -需要填写的配置: +编辑 `deploy/.env.production`,填写飞书应用配置: ```env # 飞书配置(必须配置) @@ -198,65 +235,157 @@ FEISHU_ENCRYPT_KEY=xxxxxxxxxxxxxxxxxxxx FEISHU_VERIFICATION_TOKEN=xxxxxxxxxxxxxxxxxxxx ``` ---- +### 数据库和 Redis 配置 -## 部署文件清单 +已预先配置好线上环境,无需修改: -| 文件 | 说明 | 用途 | -|------|------|------| -| `deploy/docker-compose.prod.yml` | 后端容器编排 | **线上使用** | -| `deploy/.env.production` | 线上环境变量 | **线上使用** | -| `deploy/nginx-1panel.conf` | Nginx 配置参考 | 1Panel 配置参考 | -| `deploy/deploy-1panel.sh` | 自动部署脚本 | 简化部署流程 | +```env +# 数据库(已配置) +DB_HOST=1Panel-mysql-XyxS +DB_PORT=3306 +DB_DATABASE=xserver +DB_USERNAME=xserver +DB_PASSWORD=NsNBSQm4b2b7SzhR -**注意**:开发和线上配置完全分离,不会互相影响: -- 开发环境使用 `docker-compose.yml` -- 线上环境使用 `deploy/docker-compose.prod.yml` +# Redis(已配置) +REDIS_HOST=1Panel-redis-pxdb +REDIS_PORT=6379 +REDIS_PASSWORD=redis_FTzdM6 +``` --- -## 验证部署 +## 使用部署脚本(可选) + +如需自动化部署,可以使用部署脚本: ```bash -# 1. 检查前端 +./deploy/deploy-1panel.sh your-server-ip +``` + +脚本功能: +- 自动上传前端静态文件 +- 自动上传后端代码 +- 自动重启后端容器 + +**注意**:使用脚本前需要先在本地执行 `npm run build` 打包前端。 + +--- + +## 部署验证 + +### 1. 检查前端 + +```bash +# 检查首页是否可访问 curl -I https://uniservice-mobile.hnxinyouhe.com -# 2. 检查 API +# 应该返回 200 OK +``` + +### 2. 检查 API + +```bash +# 检查 API 是否正常(需要有效的 token) curl https://uniservice-mobile.hnxinyouhe.com/api/v1/user/info \ -H "Authorization: Bearer YOUR_TOKEN" +``` -# 3. 检查后端容器 -ssh root@server +### 3. 检查后端容器 + +```bash +ssh root@your-server docker ps | grep x-server +# 应该看到 x-server-backend-prod 容器 + docker logs -f x-server-backend-prod +# 查看后端日志 +``` + +### 4. 检查 Nginx 日志 + +```bash +# 在 1Panel 面板中查看 +# 或者直接查看日志文件 +tail -f /www/sites/uniservice-mobile.hnxinyouhe.com/log/access.log ``` --- ## 常见问题 -### Q: 前端显示但 API 调用失败? -A: 检查 1Panel Nginx 配置是否添加了 `/api/` 的反向代理规则。 +### Q1: 前端显示但 API 调用 404? +**A**: 检查 1Panel Nginx 配置中是否添加了 `/api/` 的反向代理规则。 -### Q: 后端容器启动失败? -A: 检查 `deploy/docker-compose.prod.yml` 中的数据库和 Redis 容器名称是否正确。 +### Q2: 后端容器启动失败? +**A**: 检查: +- 数据库和 Redis 容器是否运行 +- Docker 网络 `1panel-network` 是否存在 +- 容器日志:`docker logs x-server-backend-prod` -### Q: 飞书登录失败? -A: 检查 `/login/*` 的反向代理规则是否已添加。 +### Q3: 飞书登录失败? +**A**: 检查 `/login/*` 的反向代理规则是否已添加。 + +### Q4: 静态资源加载 404? +**A**: 确认前端上传到了正确的目录:`/www/sites/uniservice-mobile.hnxinyouhe.com/index/` + +### Q5: 前端页面空白? +**A**: 检查: +- 确认前端打包成功:`ls frontend/dist/` 是否有 `index.html` +- 检查浏览器控制台是否有错误 + +--- + +## 开发环境 vs 生产环境 + +| 项目 | 开发环境 | 生产环境 | +|------|---------|---------| +| **前端** | `npm run dev` (Vite 开发服务器) | `npm run build` + 上传静态文件 | +| **后端** | `docker-compose.yml` | `deploy/docker-compose.prod.yml` | +| **API 地址** | `http://localhost:8787/api/v1` | `/api/v1` (相对路径) | +| **数据** | 本地数据库或开发数据库 | 线上数据库 | --- ## 回滚操作 -```bash -# 使用备份回滚 -ssh root@server -cd /www/sites/uniservice-mobile.hnxinyouhe.com -cp -r backup/YYYYMMDD_HHMMSS/* index/ +### 前端回滚 -# 重启后端容器到指定版本 +```bash +# 从之前的备份恢复 +ssh root@your-server +cp -r /www/sites/uniservice-mobile.hnxinyouhe.com/backup/YYYYMMDD_HHMMSS/* \ + /www/sites/uniservice-mobile.hnxinyouhe.com/index/ +``` + +### 后端回滚 + +```bash +ssh root@your-server cd /opt/x-server-mobile -git log # 查看提交历史 -git checkout # 切换到指定版本 + +# 切换到之前的提交 +git log --oneline +git checkout + +# 重新构建并启动 docker-compose -f deploy/docker-compose.prod.yml up -d --build ``` + +--- + +## 文件清单 + +部署相关的所有文件: + +| 文件 | 用途 | +|------|------| +| `deploy/docker-compose.prod.yml` | 线上后端容器配置 | +| `deploy/.env.production` | 线上环境变量 | +| `deploy/nginx-1panel.conf` | Nginx 配置参考 | +| `deploy/deploy-1panel.sh` | 自动部署脚本 | +| `docs/DEPLOY_ONLINE_GUIDE.md` | 本文档 | + +**注意**: +- 开发环境配置(`docker-compose.yml`)与线上环境完全分离 +- 部署文件都在 `deploy/` 目录,不会影响开发环境配置