部署运维

生产部署

本章节介绍如何将 EduBuddy 部署到 Linux 生产服务器,包含构建、Nginx 反向代理、systemd 服务管理等完整流程。

生产部署前请务必:修改 JWT_SECRET 为强随机字符串;将 NODE_ENV 设为 production;配置 HTTPS(SSL/TLS);限制 CORS Origin 为你的实际域名。

第一步:服务器准备

推荐使用 Ubuntu 22.04 LTS,安装必要的系统依赖:

# 更新系统
sudo apt update && sudo apt upgrade -y

# 安装 Node.js 20.x
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs

# 安装编译工具(better-sqlite3 需要)
sudo apt install -y build-essential python3

# 安装 Nginx
sudo apt install -y nginx

# 验证安装
node --version    # v20.x.x
npm --version     # 10.x.x
nginx -version    # nginx/1.x.x

第二步:部署代码

# 克隆项目到服务器
git clone https://github.ibm.com/xzwangdl/EduBuddy.git /opt/edubuddy
cd /opt/edubuddy

# 安装依赖
cd backend && npm install --production=false
cd ../frontend && npm install

第三步:配置环境变量

cp /opt/edubuddy/backend/.env.example /opt/edubuddy/backend/.env
nano /opt/edubuddy/backend/.env

生产环境必须修改以下配置:

# AI API(必填)
OPENAI_API_KEY=sk-your-production-api-key
OPENAI_BASE_URL=https://api.openai.com/v1
OPENAI_MODEL=gpt-4o

# 生产环境标识
NODE_ENV=production
PORT=3001

# 安全密钥(必须修改!)
JWT_SECRET=your-very-long-random-secret-at-least-64-chars

# 数据库路径(建议绝对路径)
DB_PATH=/opt/edubuddy/data/edubuddy.db

# 上传目录(建议绝对路径)
UPLOAD_DIR=/opt/edubuddy/uploads

第四步:构建项目

# 构建前端静态文件
cd /opt/edubuddy/frontend
npm run build
# 构建产物输出到 frontend/dist/

# 构建后端 TypeScript
cd /opt/edubuddy/backend
npm run build
# 编译产物输出到 backend/dist/

第五步:配置 systemd 服务

创建 systemd 服务文件,实现开机自启和故障重启:

sudo nano /etc/systemd/system/edubuddy.service
[Unit]
Description=EduBuddy Backend Service
After=network.target

[Service]
Type=simple
User=www-data
WorkingDirectory=/opt/edubuddy/backend
ExecStart=/usr/bin/node dist/server.js
Restart=on-failure
RestartSec=10
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=edubuddy
Environment=NODE_ENV=production

[Install]
WantedBy=multi-user.target
# 设置目录权限
sudo chown -R www-data:www-data /opt/edubuddy/data
sudo chown -R www-data:www-data /opt/edubuddy/uploads
sudo mkdir -p /opt/edubuddy/data /opt/edubuddy/uploads

# 启用并启动服务
sudo systemctl daemon-reload
sudo systemctl enable edubuddy
sudo systemctl start edubuddy

# 查看服务状态
sudo systemctl status edubuddy

# 查看日志
sudo journalctl -u edubuddy -f

第六步:配置 Nginx 反向代理

创建 Nginx 站点配置,前端静态文件和后端 API 通过同一域名提供:

sudo nano /etc/nginx/sites-available/edubuddy
server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;

    # 前端静态文件
    root /opt/edubuddy/frontend/dist;
    index index.html;

    # 前端 SPA 路由(所有非 API 请求返回 index.html)
    location / {
        try_files $uri $uri/ /index.html;
    }

    # 后端 API 反向代理
    location /api/ {
        proxy_pass http://127.0.0.1:3001;
        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;
        proxy_read_timeout 120s;  # 文件上传/AI 调用超时
    }

    # 上传文件静态服务
    location /uploads/ {
        alias /opt/edubuddy/uploads/;
        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    # Gzip 压缩
    gzip on;
    gzip_types text/plain text/css application/json application/javascript;
    gzip_min_length 1024;
}
# 启用站点
sudo ln -s /etc/nginx/sites-available/edubuddy /etc/nginx/sites-enabled/
sudo nginx -t          # 验证配置
sudo systemctl reload nginx

第七步:配置 HTTPS(Let's Encrypt)

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

# 申请证书(自动修改 Nginx 配置)
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

# 验证自动续期
sudo certbot renew --dry-run

第八步:修改 CORS 配置

生产环境需将 CORS 的 origin 修改为实际域名,编辑 backend/src/server.ts

app.use(cors({
  origin: process.env.NODE_ENV === 'production'
    ? ['https://yourdomain.com', 'https://www.yourdomain.com']
    : ['http://localhost:3000', 'http://localhost:5173'],
  credentials: true
}));

修改后重新构建并重启服务:

cd /opt/edubuddy/backend
npm run build
sudo systemctl restart edubuddy

数据库备份

建议配置定时备份任务(crontab):

sudo crontab -e -u www-data
# 每天凌晨 2 点备份数据库(保留 30 天)
0 2 * * * sqlite3 /opt/edubuddy/data/edubuddy.db ".backup /opt/edubuddy/backups/edubuddy-$(date +\%Y\%m\%d).db" && find /opt/edubuddy/backups -name "*.db" -mtime +30 -delete

版本更新流程

cd /opt/edubuddy

# 拉取最新代码
git pull origin main

# 重新安装依赖(如有变更)
cd backend && npm install
cd ../frontend && npm install

# 重新构建
cd /opt/edubuddy/frontend && npm run build
cd /opt/edubuddy/backend && npm run build

# 重启后端服务
sudo systemctl restart edubuddy