# Mobile Upgrade Admin - 部署指南 ## 部署概述 本文档描述 Mobile Upgrade Admin 前端应用的部署方案,包括本地构建、Docker 容器化和生产环境部署。 ## 部署架构 ``` ┌─────────────────────────────────────────────────────────────┐ │ Nginx / Caddy │ │ (Reverse Proxy) │ └─────────────────┬───────────────────────┬───────────────────┘ │ │ ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ │ Mobile Upgrade │ │ Admin Service │ │ Frontend (3001)│ │ Backend (3000) │ └─────────────────┘ └─────────────────┘ ``` ## 环境要求 | 环境 | 要求 | |------|------| | Node.js | >= 18.x | | npm | >= 9.x | | Docker | >= 20.x (可选) | | 内存 | >= 512MB | | 磁盘 | >= 500MB | ## 环境变量配置 ### 开发环境 ```bash # .env.local NEXT_PUBLIC_API_URL=http://localhost:3000 ``` ### 生产环境 ```bash # .env.production NEXT_PUBLIC_API_URL=https://api.example.com ``` | 变量 | 说明 | 默认值 | |------|------|--------| | NEXT_PUBLIC_API_URL | Admin Service API 地址 | http://localhost:3000 | | PORT | 应用监听端口 | 3000 | ## 部署方式 ### 方式一:本地构建部署 #### 1. 构建生产版本 ```bash cd frontend/mobile-upgrade # 安装依赖 npm ci # 构建 npm run build ``` 构建产物在 `.next/` 目录。 #### 2. 启动生产服务 ```bash # 使用 Node.js 直接运行 npm run start # 或指定端口 PORT=3001 npm run start ``` #### 3. 使用 PM2 管理 ```bash # 安装 PM2 npm install -g pm2 # 启动应用 pm2 start npm --name "mobile-upgrade" -- start # 查看状态 pm2 status # 查看日志 pm2 logs mobile-upgrade # 重启 pm2 restart mobile-upgrade # 停止 pm2 stop mobile-upgrade ``` PM2 配置文件: ```javascript // ecosystem.config.js module.exports = { apps: [{ name: 'mobile-upgrade', script: 'npm', args: 'start', cwd: '/path/to/mobile-upgrade', env: { NODE_ENV: 'production', PORT: 3001, }, instances: 1, autorestart: true, watch: false, max_memory_restart: '500M', }], } ``` ### 方式二:Docker 容器部署 #### 1. Dockerfile ```dockerfile # Dockerfile FROM node:18-alpine AS base # 安装依赖阶段 FROM base AS deps WORKDIR /app COPY package.json package-lock.json ./ RUN npm ci # 构建阶段 FROM base AS builder WORKDIR /app COPY --from=deps /app/node_modules ./node_modules COPY . . # 设置环境变量 ARG NEXT_PUBLIC_API_URL ENV NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL} RUN npm run build # 运行阶段 FROM base AS runner WORKDIR /app ENV NODE_ENV production RUN addgroup --system --gid 1001 nodejs RUN adduser --system --uid 1001 nextjs COPY --from=builder /app/public ./public # 复制构建产物 COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static USER nextjs EXPOSE 3000 ENV PORT 3000 ENV HOSTNAME "0.0.0.0" CMD ["node", "server.js"] ``` #### 2. 更新 next.config.js ```javascript // next.config.js /** @type {import('next').NextConfig} */ const nextConfig = { output: 'standalone', // 启用独立输出模式 // ... 其他配置 } module.exports = nextConfig ``` #### 3. 构建 Docker 镜像 ```bash # 构建镜像 docker build \ --build-arg NEXT_PUBLIC_API_URL=https://api.example.com \ -t mobile-upgrade:latest \ . # 运行容器 docker run -d \ --name mobile-upgrade \ -p 3001:3000 \ mobile-upgrade:latest ``` #### 4. Docker Compose ```yaml # docker-compose.yml version: '3.8' services: mobile-upgrade: build: context: . args: NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-http://admin-service:3000} image: mobile-upgrade:latest container_name: mobile-upgrade ports: - "3001:3000" environment: - NODE_ENV=production restart: unless-stopped networks: - rwa-network depends_on: - admin-service networks: rwa-network: external: true ``` 启动命令: ```bash # 启动 docker-compose up -d # 查看日志 docker-compose logs -f mobile-upgrade # 停止 docker-compose down ``` ### 方式三:静态导出部署 适用于不需要 SSR 的场景。 #### 1. 配置静态导出 ```javascript // next.config.js /** @type {import('next').NextConfig} */ const nextConfig = { output: 'export', trailingSlash: true, images: { unoptimized: true, }, } module.exports = nextConfig ``` #### 2. 构建静态文件 ```bash npm run build ``` 静态文件输出到 `out/` 目录。 #### 3. 使用 Nginx 部署 ```nginx # nginx.conf server { listen 80; server_name upgrade.example.com; root /var/www/mobile-upgrade; location / { try_files $uri $uri/ /index.html; } location /api { proxy_pass http://admin-service:3000; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } ``` ## 反向代理配置 ### Nginx 配置 ```nginx # /etc/nginx/sites-available/mobile-upgrade upstream mobile_upgrade { server 127.0.0.1:3001; } upstream admin_service { server 127.0.0.1:3000; } server { listen 80; server_name upgrade.example.com; # 前端应用 location / { proxy_pass http://mobile_upgrade; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } # API 代理 location /api { proxy_pass http://admin_service; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 大文件上传支持 client_max_body_size 200M; proxy_read_timeout 300s; proxy_connect_timeout 75s; } } ``` ### Caddy 配置 ```caddyfile # Caddyfile upgrade.example.com { reverse_proxy /api/* admin-service:3000 reverse_proxy /* mobile-upgrade:3001 } ``` ## 健康检查 ### 应用健康检查 ```typescript // src/app/api/health/route.ts export async function GET() { return Response.json({ status: 'healthy', timestamp: new Date().toISOString(), }) } ``` ### Docker 健康检查 ```dockerfile HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ CMD wget --no-verbose --tries=1 --spider http://localhost:3000/api/health || exit 1 ``` ### Kubernetes 探针 ```yaml livenessProbe: httpGet: path: /api/health port: 3000 initialDelaySeconds: 10 periodSeconds: 30 readinessProbe: httpGet: path: /api/health port: 3000 initialDelaySeconds: 5 periodSeconds: 10 ``` ## CI/CD 集成 ### GitHub Actions ```yaml # .github/workflows/deploy.yml name: Deploy on: push: branches: [main] paths: - 'frontend/mobile-upgrade/**' jobs: build-and-deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Setup Node.js uses: actions/setup-node@v3 with: node-version: 18 cache: 'npm' cache-dependency-path: frontend/mobile-upgrade/package-lock.json - name: Install dependencies working-directory: frontend/mobile-upgrade run: npm ci - name: Build working-directory: frontend/mobile-upgrade run: npm run build env: NEXT_PUBLIC_API_URL: ${{ secrets.API_URL }} - name: Build Docker image working-directory: frontend/mobile-upgrade run: | docker build \ --build-arg NEXT_PUBLIC_API_URL=${{ secrets.API_URL }} \ -t mobile-upgrade:${{ github.sha }} \ . - name: Push to registry run: | docker tag mobile-upgrade:${{ github.sha }} registry.example.com/mobile-upgrade:${{ github.sha }} docker push registry.example.com/mobile-upgrade:${{ github.sha }} - name: Deploy to server uses: appleboy/ssh-action@master with: host: ${{ secrets.SERVER_HOST }} username: ${{ secrets.SERVER_USER }} key: ${{ secrets.SERVER_SSH_KEY }} script: | docker pull registry.example.com/mobile-upgrade:${{ github.sha }} docker stop mobile-upgrade || true docker rm mobile-upgrade || true docker run -d \ --name mobile-upgrade \ -p 3001:3000 \ --restart unless-stopped \ registry.example.com/mobile-upgrade:${{ github.sha }} ``` ## 监控和日志 ### 日志收集 ```bash # Docker 日志 docker logs -f mobile-upgrade # PM2 日志 pm2 logs mobile-upgrade # 日志文件位置 /var/log/mobile-upgrade/access.log /var/log/mobile-upgrade/error.log ``` ### 性能监控 建议集成: - **Prometheus + Grafana**: 指标监控 - **Sentry**: 错误追踪 - **Datadog / New Relic**: APM ### 集成 Sentry ```bash npm install @sentry/nextjs ``` ```typescript // sentry.client.config.ts import * as Sentry from '@sentry/nextjs' Sentry.init({ dsn: process.env.NEXT_PUBLIC_SENTRY_DSN, tracesSampleRate: 0.1, }) ``` ## 故障排查 ### 常见问题 | 问题 | 可能原因 | 解决方案 | |------|----------|----------| | 页面空白 | 构建失败 | 检查构建日志 | | API 请求失败 | CORS / 网络 | 检查代理配置 | | 静态资源 404 | 路径配置 | 检查 basePath 配置 | | 内存不足 | 并发过高 | 增加实例或内存 | ### 调试命令 ```bash # 检查进程 ps aux | grep node # 检查端口 netstat -tlnp | grep 3001 # 检查容器 docker ps -a docker inspect mobile-upgrade # 检查日志 docker logs --tail 100 mobile-upgrade ``` ## 回滚策略 ### Docker 回滚 ```bash # 查看历史版本 docker images mobile-upgrade # 回滚到指定版本 docker stop mobile-upgrade docker rm mobile-upgrade docker run -d \ --name mobile-upgrade \ -p 3001:3000 \ mobile-upgrade:previous-tag ``` ### PM2 回滚 ```bash # 保存当前配置 pm2 save # 回滚 pm2 reload ecosystem.config.js --update-env ``` ## 安全建议 1. **环境变量**:不要在代码中硬编码敏感信息 2. **HTTPS**:生产环境强制使用 HTTPS 3. **CSP**:配置内容安全策略 4. **更新依赖**:定期更新依赖修复安全漏洞 5. **访问控制**:配置合适的访问权限 ## 相关文档 - [架构文档](./ARCHITECTURE.md) - [API 文档](./API.md) - [开发指南](./DEVELOPMENT.md) - [测试指南](./TESTING.md)