MBE Education 部署指南

📋 目录


🔧 环境准备

系统要求

操作系统:
  - Linux (Ubuntu 20.04+, CentOS 8+)
  - macOS 11+
  - Windows 10/11 + WSL2

硬件要求 (最低):
  - CPU: 2核
  - 内存: 4GB
  - 硬盘: 20GB

硬件要求 (推荐):
  - CPU: 4核
  - 内存: 8GB
  - 硬盘: 50GB

软件依赖

前端

# Node.js (推荐使用nvm管理)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
nvm install 18
nvm use 18

# 验证安装
node --version  # >= 18.0.0
npm --version   # >= 9.0.0

后端

# Python
sudo apt update
sudo apt install python3.10 python3.10-venv python3-pip

# 验证安装
python3 --version  # >= 3.10
pip3 --version     # >= 23.0

数据库 (可选)

# PostgreSQL
sudo apt install postgresql postgresql-contrib

# Redis
sudo apt install redis-server

💻 本地开发

快速启动脚本

创建 start-dev.sh:

#!/bin/bash

echo "🚀 启动MBE Education开发环境..."

# 启动后端
cd backend
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
python scripts/run_simple_api.py &
BACKEND_PID=$!

# 启动前端
cd ../frontend
npm install
npm run dev &
FRONTEND_PID=$!

echo "✅ 服务已启动"
echo "   前端: http://localhost:3000"
echo "   后端: http://localhost:8000"
echo ""
echo "按Ctrl+C停止服务"

# 等待中断信号
trap "kill $BACKEND_PID $FRONTEND_PID" SIGINT
wait

使用:

chmod +x start-dev.sh
./start-dev.sh

PowerShell启动脚本 (Windows)

创建 start-dev.ps1:

Write-Host "🚀 启动MBE Education开发环境..." -ForegroundColor Green

# 启动后端
Start-Process powershell -ArgumentList "-NoExit", "-Command", "cd backend; python -m venv venv; .\venv\Scripts\Activate.ps1; pip install -r requirements.txt; python scripts\run_simple_api.py"

# 等待2秒
Start-Sleep -Seconds 2

# 启动前端
Start-Process powershell -ArgumentList "-NoExit", "-Command", "cd frontend; npm install; npm run dev"

Write-Host "✅ 服务已启动" -ForegroundColor Green
Write-Host "   前端: http://localhost:3000"
Write-Host "   后端: http://localhost:8000"

使用:

.\start-dev.ps1

🚀 生产部署

1. 前端部署 (Next.js)

构建生产版本

cd frontend

# 安装依赖
npm ci --production

# 构建
npm run build

# 测试构建
npm run start

使用PM2管理

# 安装PM2
npm install -g pm2

# 启动应用
pm2 start npm --name "mbe-frontend" -- start

# 保存PM2配置
pm2 save

# 设置开机自启
pm2 startup

PM2配置文件

创建 ecosystem.config.js:

module.exports = {
  apps: [{
    name: 'mbe-frontend',
    script: 'npm',
    args: 'start',
    cwd: './frontend',
    instances: 2,
    exec_mode: 'cluster',
    env: {
      NODE_ENV: 'production',
      PORT: 3000
    }
  }]
};

启动:

pm2 start ecosystem.config.js

2. 后端部署 (FastAPI)

使用Gunicorn + Uvicorn

cd backend

# 安装Gunicorn
pip install gunicorn

# 启动服务器
gunicorn main:app \
  -w 4 \
  -k uvicorn.workers.UvicornWorker \
  --bind 0.0.0.0:8000 \
  --access-logfile logs/access.log \
  --error-logfile logs/error.log \
  --log-level info

Systemd服务配置

创建 /etc/systemd/system/mbe-backend.service:

[Unit]
Description=MBE Education Backend
After=network.target

[Service]
Type=notify
User=www-data
Group=www-data
WorkingDirectory=/var/www/mbe-education/backend
Environment="PATH=/var/www/mbe-education/backend/venv/bin"
ExecStart=/var/www/mbe-education/backend/venv/bin/gunicorn \
  -w 4 \
  -k uvicorn.workers.UvicornWorker \
  --bind 0.0.0.0:8000 \
  main:app

Restart=always

[Install]
WantedBy=multi-user.target

启动服务:

sudo systemctl daemon-reload
sudo systemctl enable mbe-backend
sudo systemctl start mbe-backend
sudo systemctl status mbe-backend

3. Nginx配置

创建 /etc/nginx/sites-available/mbe-education:

# HTTP → HTTPS重定向
server {
    listen 80;
    server_name mbe-education.com www.mbe-education.com;
    return 301 https://$server_name$request_uri;
}

# HTTPS主配置
server {
    listen 443 ssl http2;
    server_name mbe-education.com www.mbe-education.com;

    # SSL证书
    ssl_certificate /etc/letsencrypt/live/mbe-education.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mbe-education.com/privkey.pem;
    
    # SSL优化
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    # 前端 (Next.js)
    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        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;
        proxy_cache_bypass $http_upgrade;
    }

    # 后端API
    location /api {
        proxy_pass http://localhost:8000;
        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;
        
        # CORS
        add_header Access-Control-Allow-Origin * always;
        add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
        add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
    }

    # 静态文件缓存
    location /_next/static/ {
        proxy_pass http://localhost:3000;
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

    # Gzip压缩
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
    gzip_min_length 1000;
}

启用配置:

sudo ln -s /etc/nginx/sites-available/mbe-education /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

4. SSL证书 (Let's Encrypt)

# 安装Certbot
sudo apt install certbot python3-certbot-nginx

# 获取证书
sudo certbot --nginx -d mbe-education.com -d www.mbe-education.com

# 测试自动续期
sudo certbot renew --dry-run

🐳 Docker部署

Dockerfile - 前端

创建 frontend/Dockerfile:

FROM node:18-alpine AS builder

WORKDIR /app

# 复制依赖文件
COPY package*.json ./
RUN npm ci

# 复制源代码
COPY . .

# 构建
RUN npm run build

# 生产镜像
FROM node:18-alpine AS runner

WORKDIR /app

ENV NODE_ENV production

# 复制必要文件
COPY --from=builder /app/public ./public
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static

EXPOSE 3000

CMD ["node", "server.js"]

Dockerfile - 后端

创建 backend/Dockerfile:

FROM python:3.10-slim

WORKDIR /app

# 安装系统依赖
RUN apt-get update && apt-get install -y \
    gcc \
    && rm -rf /var/lib/apt/lists/*

# 复制依赖文件
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# 复制源代码
COPY . .

# 暴露端口
EXPOSE 8000

# 启动命令
CMD ["gunicorn", "-w", "4", "-k", "uvicorn.workers.UvicornWorker", "--bind", "0.0.0.0:8000", "main:app"]

Docker Compose

创建 docker-compose.yml:

version: '3.8'

services:
  # PostgreSQL数据库
  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: mbe_education
      POSTGRES_USER: mbe
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - mbe-network
    restart: unless-stopped

  # Redis缓存
  redis:
    image: redis:7-alpine
    command: redis-server --appendonly yes
    volumes:
      - redis_data:/data
    networks:
      - mbe-network
    restart: unless-stopped

  # 后端API
  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
    environment:
      DATABASE_URL: postgresql://mbe:${DB_PASSWORD}@db:5432/mbe_education
      REDIS_URL: redis://redis:6379
      OPENAI_API_KEY: ${OPENAI_API_KEY}
      SECRET_KEY: ${SECRET_KEY}
    ports:
      - "8000:8000"
    depends_on:
      - db
      - redis
    networks:
      - mbe-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/api/expert/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  # 前端应用
  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
    environment:
      NEXT_PUBLIC_API_URL: http://backend:8000
    ports:
      - "3000:3000"
    depends_on:
      - backend
    networks:
      - mbe-network
    restart: unless-stopped

  # Nginx反向代理
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./ssl:/etc/nginx/ssl:ro
    depends_on:
      - frontend
      - backend
    networks:
      - mbe-network
    restart: unless-stopped

networks:
  mbe-network:
    driver: bridge

volumes:
  postgres_data:
  redis_data:

环境变量文件

创建 .env:

# 数据库
DB_PASSWORD=your-secure-password

# API密钥
OPENAI_API_KEY=sk-xxx

# 安全
SECRET_KEY=your-secret-key-here

# 环境
NODE_ENV=production

启动Docker服务

# 构建镜像
docker-compose build

# 启动服务
docker-compose up -d

# 查看日志
docker-compose logs -f

# 停止服务
docker-compose down

# 清理所有数据
docker-compose down -v

☁️ 云平台部署

Vercel (前端)

1. 连接GitHub

在Vercel控制台连接GitHub仓库

2. 配置环境变量

NEXT_PUBLIC_API_URL=https://api.mbe-education.com
NODE_ENV=production

3. 构建设置

{
  "buildCommand": "npm run build",
  "outputDirectory": ".next",
  "installCommand": "npm ci"
}

4. 部署

# 使用Vercel CLI
npm i -g vercel
vercel --prod

AWS (后端)

使用EC2

# 1. 启动EC2实例 (Ubuntu 22.04)
# 2. SSH连接
ssh -i your-key.pem ubuntu@ec2-instance-ip

# 3. 安装依赖
sudo apt update
sudo apt install python3.10 python3-pip nginx

# 4. 克隆代码
git clone https://github.com/your-org/mbe-education.git
cd mbe-education/backend

# 5. 安装Python依赖
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

# 6. 配置Nginx (见上文)
# 7. 启动服务 (见上文)

使用ECS (Docker)

# 1. 推送镜像到ECR
aws ecr create-repository --repository-name mbe-backend

# 2. 构建并推送
docker build -t mbe-backend .
docker tag mbe-backend:latest ${AWS_ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com/mbe-backend:latest
docker push ${AWS_ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com/mbe-backend:latest

# 3. 创建ECS任务定义
# 4. 启动ECS服务

Digital Ocean App Platform

创建 app.yaml:

name: mbe-education

services:
  - name: backend
    github:
      repo: your-org/mbe-education
      branch: main
      deploy_on_push: true
    source_dir: /backend
    run_command: gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app
    envs:
      - key: DATABASE_URL
        value: ${db.DATABASE_URL}
      - key: OPENAI_API_KEY
        value: ${OPENAI_API_KEY}
        type: SECRET
    http_port: 8000

  - name: frontend
    github:
      repo: your-org/mbe-education
      branch: main
    source_dir: /frontend
    build_command: npm run build
    run_command: npm start
    envs:
      - key: NEXT_PUBLIC_API_URL
        value: ${backend.URL}
    http_port: 3000

databases:
  - name: db
    engine: PG
    version: "15"

部署:

doctl apps create --spec app.yaml

📊 监控和维护

系统监控

安装监控工具

# 安装Prometheus
wget https://github.com/prometheus/prometheus/releases/download/v2.40.0/prometheus-2.40.0.linux-amd64.tar.gz
tar xvfz prometheus-*.tar.gz
cd prometheus-*

# 配置prometheus.yml
# 启动
./prometheus --config.file=prometheus.yml

# 安装Grafana
sudo apt-get install -y grafana
sudo systemctl start grafana-server
sudo systemctl enable grafana-server

日志管理

# 安装Loki + Promtail
wget https://github.com/grafana/loki/releases/download/v2.7.0/loki-linux-amd64.zip
unzip loki-linux-amd64.zip

# 启动Loki
./loki-linux-amd64 -config.file=loki-config.yaml

备份策略

数据库备份

创建 backup.sh:

#!/bin/bash

# 配置
DB_NAME="mbe_education"
DB_USER="mbe"
BACKUP_DIR="/var/backups/mbe"
DATE=$(date +%Y%m%d_%H%M%S)

# 创建备份目录
mkdir -p $BACKUP_DIR

# 备份数据库
pg_dump -U $DB_USER $DB_NAME | gzip > $BACKUP_DIR/db_backup_$DATE.sql.gz

# 删除7天前的备份
find $BACKUP_DIR -name "db_backup_*.sql.gz" -mtime +7 -delete

echo "✅ 备份完成: $BACKUP_DIR/db_backup_$DATE.sql.gz"

定时备份 (Cron)

# 编辑crontab
crontab -e

# 每天凌晨2点备份
0 2 * * * /path/to/backup.sh

性能监控

监控API性能

# 添加到FastAPI应用
from fastapi import Request
import time

@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    start_time = time.time()
    response = await call_next(request)
    process_time = time.time() - start_time
    response.headers["X-Process-Time"] = str(process_time)
    return response

监控前端性能

// 使用Web Vitals
import { getCLS, getFID, getFCP, getLCP, getTTFB } from 'web-vitals';

function sendToAnalytics(metric: any) {
  // 发送到分析服务
  console.log(metric);
}

getCLS(sendToAnalytics);
getFID(sendToAnalytics);
getFCP(sendToAnalytics);
getLCP(sendToAnalytics);
getTTFB(sendToAnalytics);

🔍 故障排查

常见问题

1. 端口被占用

# 查找占用端口的进程
sudo lsof -i :3000
sudo lsof -i :8000

# 终止进程
kill -9 <PID>

2. 内存不足

# 查看内存使用
free -h

# 清理缓存
sudo sh -c 'echo 3 > /proc/sys/vm/drop_caches'

# 增加swap
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

3. 数据库连接失败

# 检查PostgreSQL状态
sudo systemctl status postgresql

# 查看日志
sudo tail -f /var/log/postgresql/postgresql-15-main.log

# 重启服务
sudo systemctl restart postgresql

日志分析

# 后端日志
tail -f logs/api.log

# Nginx访问日志
tail -f /var/log/nginx/access.log

# Nginx错误日志
tail -f /var/log/nginx/error.log

# 系统日志
sudo journalctl -u mbe-backend -f

📝 检查清单

部署前检查

  • 所有环境变量已配置
  • 数据库已迁移
  • SSL证书已安装
  • 防火墙规则已配置
  • 备份策略已实施
  • 监控系统已部署
  • 日志收集已配置
  • 性能测试已完成

部署后验证

  • 前端可正常访问
  • API端点正常响应
  • 数据库连接正常
  • SSL证书有效
  • 监控数据正常上报
  • 日志正常记录
  • 备份任务正常执行

版本: 1.0.0
更新时间: 2026-02-02
作者: MBE Education DevOps Team