Files
gamegroup/doc/deployment/部署指导文档.md
UGREEN USER b25aa5b143 初始化游戏小组管理系统后端项目
- 基于 NestJS + TypeScript + MySQL + Redis 架构
- 完整的模块化设计(认证、用户、小组、游戏、预约等)
- JWT 认证和 RBAC 权限控制系统
- Docker 容器化部署支持
- 添加 CLAUDE.md 项目开发指南
- 配置 .gitignore 忽略文件

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-28 10:42:06 +08:00

17 KiB
Raw Blame History

GameGroup 后端部署指导文档

目录


环境准备

系统要求

  • Node.js: 18.x 或更高版本
  • MySQL: 8.0 或更高版本
  • 内存: 最低 2GB RAM推荐 4GB+
  • 存储: 最低 10GB 可用空间

必需软件

# 检查 Node.js 版本
node --version  # 应该 >= 18.0.0

# 检查 npm 版本
npm --version

# 检查 MySQL 版本
mysql --version  # 应该 >= 8.0

本地开发部署

1. 克隆项目并安装依赖

# 进入项目目录
cd d:\vscProg\backend

# 安装依赖
npm install

2. 配置环境变量

复制环境变量示例文件:

cp .env.example .env.development

编辑 .env.development 文件:

# 应用配置
NODE_ENV=development
PORT=3000

# 数据库配置
DB_TYPE=mysql
DB_HOST=localhost
DB_PORT=3306
DB_USERNAME=root
DB_PASSWORD=你的数据库密码
DB_DATABASE=gamegroup
DB_SYNCHRONIZE=true
DB_LOGGING=true

# JWT配置
JWT_SECRET=dev-secret-key-change-in-production
JWT_EXPIRES_IN=7d

# CORS配置
CORS_ORIGIN=http://localhost:8080

# 日志配置
LOG_LEVEL=debug

# 缓存配置
CACHE_TTL=300
CACHE_MAX=100

# 性能配置
ENABLE_COMPRESSION=true
QUERY_LIMIT=100
QUERY_TIMEOUT=30000

3. 创建数据库

# 登录 MySQL
mysql -u root -p

# 创建数据库
CREATE DATABASE gamegroup CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

# 创建用户(可选)
CREATE USER 'gamegroup'@'localhost' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON gamegroup.* TO 'gamegroup'@'localhost';
FLUSH PRIVILEGES;
EXIT;

4. 启动开发服务器

# 启动开发模式(支持热重载)
npm run start:dev

# 或者普通启动
npm run start

访问 http://localhost:3000 查看应用是否正常运行。 访问 http://localhost:3000/docs 查看 Swagger API 文档。

5. 运行测试

# 运行所有测试
npm test

# 运行测试并生成覆盖率报告
npm run test:cov

# 监听模式运行测试
npm run test:watch

生产环境部署

方式一Docker 部署(推荐)

1. 准备配置文件

创建 .env.production 文件:

NODE_ENV=production
PORT=3000

# 数据库配置(使用强密码!)
DB_HOST=mysql
DB_PORT=3306
DB_USERNAME=gamegroup
DB_PASSWORD=生产环境强密码
DB_DATABASE=gamegroup
DB_SYNCHRONIZE=false
DB_LOGGING=false
DB_ROOT_PASSWORD=MySQL_Root强密码

# JWT配置必须更换
JWT_SECRET=生产环境超长随机密钥_至少32位
JWT_EXPIRES_IN=7d

# CORS配置限制为实际前端域名
CORS_ORIGIN=https://your-frontend-domain.com

# 日志配置
LOG_LEVEL=info

# 缓存配置
CACHE_TTL=600
CACHE_MAX=1000

# 性能配置
ENABLE_COMPRESSION=true
QUERY_LIMIT=100
QUERY_TIMEOUT=30000

2. 构建和启动

# 构建生产镜像
docker-compose -f docker-compose.prod.yml build

# 启动服务(后台运行)
docker-compose -f docker-compose.prod.yml up -d

# 查看运行状态
docker-compose -f docker-compose.prod.yml ps

# 查看日志
docker-compose -f docker-compose.prod.yml logs -f backend

3. 健康检查

# 检查应用健康状态
curl http://localhost:3000/health

# 检查容器状态
docker ps

# 查看容器资源使用
docker stats

4. 停止服务

# 停止服务
docker-compose -f docker-compose.prod.yml down

# 停止服务并删除数据卷(谨慎使用!)
docker-compose -f docker-compose.prod.yml down -v

方式二PM2 部署

1. 安装 PM2

npm install -g pm2

2. 构建应用

# 安装生产依赖
npm ci --only=production

# 构建项目
npm run build:prod

3. 启动应用

# 使用 PM2 启动
pm2 start ecosystem.config.js --env production

# 查看运行状态
pm2 status

# 查看日志
pm2 logs gamegroup-backend

# 查看实时监控
pm2 monit

4. 设置开机自启

# 保存当前 PM2 进程列表
pm2 save

# 设置开机自启
pm2 startup

# 根据提示执行相应命令(会因系统而异)

5. 常用 PM2 命令

# 重启应用
pm2 restart gamegroup-backend

# 停止应用
pm2 stop gamegroup-backend

# 删除应用
pm2 delete gamegroup-backend

# 重载应用(零停机重启)
pm2 reload gamegroup-backend

# 查看详细信息
pm2 show gamegroup-backend

# 清空日志
pm2 flush

方式三:直接使用 Node.js

1. 构建应用

npm run build:prod

2. 启动应用

# 设置环境变量并启动
export NODE_ENV=production
node dist/main.js

# 或使用 npm 脚本
npm run start:prod

⚠️ 不推荐直接使用 Node.js,因为没有进程管理和自动重启功能。


数据库配置

创建生产数据库

-- 创建数据库
CREATE DATABASE gamegroup 
  CHARACTER SET utf8mb4 
  COLLATE utf8mb4_unicode_ci;

-- 创建专用用户
CREATE USER 'gamegroup'@'%' IDENTIFIED BY '强密码';

-- 授予权限
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, INDEX, ALTER 
  ON gamegroup.* 
  TO 'gamegroup'@'%';

FLUSH PRIVILEGES;

性能优化索引

USE gamegroup;

-- 用户表索引
CREATE INDEX idx_user_username ON user(username);
CREATE INDEX idx_user_email ON user(email);
CREATE INDEX idx_user_phone ON user(phone);
CREATE INDEX idx_user_is_member ON user(isMember);

-- 小组表索引
CREATE INDEX idx_group_owner ON `group`(ownerId);
CREATE INDEX idx_group_is_active ON `group`(isActive);
CREATE INDEX idx_group_is_public ON `group`(isPublic);
CREATE INDEX idx_group_created_at ON `group`(createdAt);

-- 小组成员表索引
CREATE INDEX idx_member_group_user ON group_member(groupId, userId);
CREATE INDEX idx_member_user ON group_member(userId);
CREATE INDEX idx_member_is_active ON group_member(isActive);
CREATE INDEX idx_member_role ON group_member(role);

-- 预约表索引
CREATE INDEX idx_appointment_group ON appointment(groupId);
CREATE INDEX idx_appointment_creator ON appointment(initiatorId);
CREATE INDEX idx_appointment_date ON appointment(eventDate);
CREATE INDEX idx_appointment_status ON appointment(status);
CREATE INDEX idx_appointment_created_at ON appointment(createdAt);

-- 预约参与者表索引
CREATE INDEX idx_participant_appointment ON appointment_participant(appointmentId);
CREATE INDEX idx_participant_user ON appointment_participant(userId);

-- 游戏表索引
CREATE INDEX idx_game_name ON game(name);
CREATE INDEX idx_game_category ON game(category);

-- 黑名单表索引
CREATE INDEX idx_blacklist_reporter ON blacklist(reporterId);
CREATE INDEX idx_blacklist_reported ON blacklist(reportedUserId);
CREATE INDEX idx_blacklist_status ON blacklist(status);

-- 荣誉墙表索引
CREATE INDEX idx_honors_group ON honors(groupId);
CREATE INDEX idx_honors_creator ON honors(creatorId);
CREATE INDEX idx_honors_year ON honors(year);

-- 积分表索引
CREATE INDEX idx_points_user ON points(userId);
CREATE INDEX idx_points_type ON points(type);
CREATE INDEX idx_points_created_at ON points(createdAt);

-- 打赌表索引
CREATE INDEX idx_bets_creator ON bets(creatorId);
CREATE INDEX idx_bets_status ON bets(status);
CREATE INDEX idx_bets_deadline ON bets(deadline);

数据库备份

# 手动备份
mysqldump -u root -p gamegroup > backup_$(date +%Y%m%d_%H%M%S).sql

# 恢复备份
mysql -u root -p gamegroup < backup_20240101_120000.sql

# 使用 Docker 备份
docker exec gamegroup-mysql-prod mysqldump -u root -p密码 gamegroup > backup.sql

# 定时备份(添加到 crontab
0 2 * * * mysqldump -u root -p密码 gamegroup > /backups/gamegroup_$(date +\%Y\%m\%d).sql

性能优化建议

1. 应用层优化

启用 HTTP 压缩

已在 main.ts 中配置,确保 .env 中设置:

ENABLE_COMPRESSION=true

缓存配置优化

根据实际流量调整缓存参数:

# 高流量场景
CACHE_TTL=600        # 10分钟
CACHE_MAX=5000       # 5000条缓存

# 中等流量
CACHE_TTL=300        # 5分钟
CACHE_MAX=1000       # 1000条缓存

# 低流量
CACHE_TTL=180        # 3分钟
CACHE_MAX=500        # 500条缓存

连接池优化

database.config.ts 中已配置:

  • 开发环境10个连接
  • 生产环境20个连接

可根据服务器配置调整。

2. 数据库优化

查询缓存

生产环境已启用数据库查询缓存1分钟

慢查询日志

-- 启用慢查询日志
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 2;
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow-query.log';

-- 查看慢查询统计
SHOW STATUS LIKE 'Slow_queries';

定期优化表

-- 优化所有表
OPTIMIZE TABLE user, `group`, group_member, appointment;

-- 分析表
ANALYZE TABLE user, `group`, group_member;

3. 服务器配置优化

Nginx 反向代理(推荐)

upstream backend {
    server localhost:3000;
    # 如果有多个实例,添加更多服务器
    # server localhost:3001;
    # server localhost:3002;
}

server {
    listen 80;
    server_name your-domain.com;

    # 请求体大小限制
    client_max_body_size 10M;

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

    location / {
        proxy_pass http://backend;
        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_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }

    # API 限流
    location /api/ {
        limit_req zone=api burst=20 nodelay;
        proxy_pass http://backend;
    }
}

# 限流配置(在 http 块中)
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;

监控和维护

1. 健康检查端点

# 应用健康检查
curl http://localhost:3000/health

# 期望响应
{"status": "ok"}

2. 日志管理

查看应用日志

# Docker 环境
docker-compose -f docker-compose.prod.yml logs -f backend

# PM2 环境
pm2 logs gamegroup-backend

# 查看错误日志
pm2 logs gamegroup-backend --err

# 查看输出日志
pm2 logs gamegroup-backend --out

日志轮转配置

PM2 日志轮转:

# 安装 PM2 日志轮转模块
pm2 install pm2-logrotate

# 配置最大日志大小
pm2 set pm2-logrotate:max_size 10M

# 配置保留天数
pm2 set pm2-logrotate:retain 7

# 配置压缩
pm2 set pm2-logrotate:compress true

3. 性能监控

内置监控

# PM2 监控
pm2 monit

# 查看详细指标
pm2 show gamegroup-backend

推荐监控工具

  • New Relic: 应用性能监控 (APM)
  • Datadog: 全栈监控
  • Prometheus + Grafana: 开源监控方案
  • ELK Stack: 日志聚合和分析

4. 数据库监控

-- 查看连接数
SHOW STATUS LIKE 'Threads_connected';

-- 查看最大连接数
SHOW VARIABLES LIKE 'max_connections';

-- 查看查询统计
SHOW STATUS LIKE 'Questions';
SHOW STATUS LIKE 'Queries';

-- 查看慢查询
SHOW STATUS LIKE 'Slow_queries';

-- 查看当前运行的查询
SHOW PROCESSLIST;

常见问题排查

1. 应用无法启动

检查端口占用

# Windows
netstat -ano | findstr :3000

# Linux/Mac
lsof -i :3000

检查环境变量

# 确认环境变量已加载
echo $NODE_ENV

# 检查配置文件
cat .env.production

查看详细错误

# Docker
docker-compose -f docker-compose.prod.yml logs backend

# PM2
pm2 logs gamegroup-backend --lines 100

2. 数据库连接失败

检查数据库服务

# 检查 MySQL 是否运行
# Windows
sc query MySQL80

# Linux
systemctl status mysql

# Docker
docker ps | grep mysql

测试数据库连接

mysql -h localhost -u gamegroup -p -D gamegroup

常见错误

  • ER_ACCESS_DENIED_ERROR: 用户名或密码错误
  • ECONNREFUSED: 数据库服务未启动或端口错误
  • ER_BAD_DB_ERROR: 数据库不存在

3. 内存占用过高

查看内存使用

# PM2
pm2 show gamegroup-backend

# Docker
docker stats gamegroup-backend-prod

解决方案

# PM2 设置内存限制(在 ecosystem.config.js 中)
max_memory_restart: '500M'

# 重启应用释放内存
pm2 restart gamegroup-backend

4. 性能问题

分析慢查询

-- 查看慢查询日志
SELECT * FROM mysql.slow_log;

-- 使用 EXPLAIN 分析查询
EXPLAIN SELECT * FROM user WHERE username = 'test';

检查缓存命中率

查看应用日志,搜索 "Cache hit" 和 "Cache miss"。

数据库优化

-- 检查表状态
SHOW TABLE STATUS LIKE 'user';

-- 优化表
OPTIMIZE TABLE user;

-- 更新统计信息
ANALYZE TABLE user;

5. Docker 相关问题

容器无法启动

# 查看容器日志
docker logs gamegroup-backend-prod

# 检查容器状态
docker inspect gamegroup-backend-prod

# 重新构建
docker-compose -f docker-compose.prod.yml build --no-cache

数据持久化问题

# 查看数据卷
docker volume ls

# 检查数据卷
docker volume inspect gamegroup_mysql-data

# 备份数据卷
docker run --rm -v gamegroup_mysql-data:/data -v $(pwd):/backup ubuntu tar czf /backup/mysql-backup.tar.gz /data

安全建议

1. 环境变量安全

  • 不要将 .env 文件提交到 Git
  • 使用强密码至少16位包含大小写字母、数字、特殊字符
  • 定期更换 JWT_SECRET
  • 限制 CORS_ORIGIN 为实际域名

2. 数据库安全

  • 不使用 root 用户连接
  • 限制数据库用户权限(不给 DROP、ALTER 等危险权限)
  • 使用防火墙限制数据库端口访问
  • 启用 SSL/TLS 连接

3. 应用安全

  • 定期更新依赖包:npm audit fix
  • 启用 HTTPS使用 Let's Encrypt 免费证书)
  • 实施请求速率限制
  • 设置 HTTP 安全头Helmet 中间件)
  • 输入验证和 SQL 注入防护(已使用 TypeORM

4. 网络安全

# 配置防火墙Ubuntu/Debian
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 22/tcp
sudo ufw deny 3306/tcp  # 拒绝外部访问数据库
sudo ufw enable

# 仅允许特定 IP 访问数据库
sudo ufw allow from 服务器IP to any port 3306

升级和回滚

应用升级

# 1. 拉取最新代码
git pull origin main

# 2. 安装依赖
npm ci

# 3. 运行测试
npm test

# 4. 构建应用
npm run build:prod

# 5. 备份数据库
mysqldump -u root -p gamegroup > backup_before_upgrade.sql

# 6. 使用 PM2 重载(零停机)
pm2 reload gamegroup-backend

# 或使用 Docker
docker-compose -f docker-compose.prod.yml up -d --build

应用回滚

# 1. 切换到上一个版本
git checkout 上一个稳定版本的commit

# 2. 重新构建和部署
npm ci
npm run build:prod
pm2 restart gamegroup-backend

# 3. 如需回滚数据库
mysql -u root -p gamegroup < backup_before_upgrade.sql

生产环境检查清单

部署前请确认以下项目:

  • 已设置强 JWT_SECRET
  • 已设置强数据库密码
  • DB_SYNCHRONIZE 设置为 false
  • DB_LOGGING 设置为 false
  • CORS_ORIGIN 限制为实际域名
  • 已创建数据库索引
  • 已配置数据库备份
  • 已设置日志轮转
  • 已配置监控告警
  • 已进行压力测试
  • 已准备回滚方案
  • 已配置 HTTPS
  • 已设置防火墙规则
  • 已配置健康检查
  • 已测试备份恢复流程

技术支持

文档参考

问题反馈

如遇到部署问题,请提供:

  1. 错误日志(完整堆栈跟踪)
  2. 环境信息Node.js、MySQL 版本)
  3. 配置文件(隐藏敏感信息)
  4. 复现步骤

祝部署顺利! 🚀