前言
一直苦于技术没有接触后端,导致技术不够全面。离职后休息这段时间,设计架构了前后端系统,从另一个层面来讲,确实迈进了一大步,遇见了之前从未遇到的Bug,从开发,到部署,到测试,也是一番新的挑战
项目介绍
该项目是一个基于 Node.js + Express + MySQL + React + Antd 的现代化全栈管理系统。后端提供 JWT 认证、审计日志与在线用户、SSE 实时通知、单点登录;前端提供动态权限路由与增强版 SSE Hook。
在线地址: https://www.liyq666.top
git仓库:https://gitee.com/lyqjob/project-root
欢迎找我要最新系统预制脚本,一键插入数据库基本数据(预制菜单、预制权限、预制角色、超级管理员)等都有
项目实例图















项目特性
后端能力
- JWT 双 Token 认证与权限控制(Access/Refresh)
- 审计日志与来源采集(Referer、X-Client-Page),列表与详情查询
- 在线用户接口(基于审计窗口聚合,含来源页面、设备信息、会话信息)
- 单点登录(SINGLE_LOGIN),登录时保留当前会话并清退其他会话;通过 SSE 发送下线通知
- SSE 实时通知(认证连接),心跳与连接统计;支持稳定客户端标识
clientId - 统一日志与请求 ID,中间件记录请求信息与敏感脱敏
- Token 管理与自动清理
- CORS 允许自定义头:
X-Client-Id、X-Client-Page
前端能力
- React 18 + Antd 5 + Webpack 5 + Redux Toolkit + React Router 6
- 动态权限路由(后端返回菜单动态注册)与按钮级权限
- 增强版
useSSEHook:自动认证、自动重连、心跳与事件订阅、稳定clientId持久化(localStorage) - 基础布局
BasicLayout集成 SSE 事件(open/welcome/heartbeat/loginout),收到登录异常通知后自动退出
项目结构
project-root/
├── node-express-mysql/ # 后端服务
│ ├── config/ # 配置(配置与实现分离)
│ │ ├── base/ # 基础配置(与环境无关)
│ │ │ ├── cache.js captcha.js code.js db.js logger.js redis.js schedules.js upload.js
│ │ ├── env/ # 环境特定配置(development/production/test)
│ │ └── index.js # 配置加载与合并导出
│ ├── docs/ # 后端文档(缓存/日志/SSE/权限规范等)
│ ├── public/ # 静态资源
│ ├── sql/ # SQL 脚本(库/表结构与初始化)
│ ├── src/ # 源代码
│ │ ├── cache/ # 缓存服务(Memory/Redis/策略/监控/键生成器)
│ │ ├── controllers/ # 控制器(auth/user/role/menu/permission/department/...)
│ │ ├── infra/ # 基础设施(dbClient/redisClient/scheduler/sseManager)
│ │ ├── logger/ # 日志模块(增强日志/核心/工具/脱敏)
│ │ ├── middlewares/ # 中间件(认证/权限/文件/验证码/请求ID/监控校验)
│ │ ├── models/ # 数据模型(user/role/menu/permission/department/token/audit/monitor)
│ │ ├── routes/ # 路由(index + 各模块路由,含 sse/publicAuth/monitor 等)
│ │ ├── services/ # 领域服务(codeService/dbService/redisService/uploadService)
│ │ └── utils/ # 工具(response/jwtUtils/validator/utils/auditLogger/codeGenerator/sseManager)
│ ├── ecosystem.config.js # PM2 配置
│ ├── swagger.yaml # OpenAPI 描述
│ ├── index.js # 应用入口
│ ├── log-rotate.sh # 日志轮转脚本
│ ├── package.json # 项目配置
│ └── README.md # 后端说明
├── react-antd-webpack/ # 前端应用
│ ├── build/ # Webpack 配置(base/dev/prod)
│ ├── public/ # 公共资源
│ ├── src/ # 源代码
│ │ ├── components/ # 通用组件(GlobalHeader/SSEManager/Audit/AuthButton/Charts 等)
│ │ ├── hooks/ # 自定义 Hook(useSSE/usePermission/useAuth 等)
│ │ ├── layouts/ # 布局(BasicLayout/authRouter)
│ │ ├── pages/ # 页面模块(login/home/monitor/setting/...)
│ │ ├── router/ # 路由(baseRouter/asynccomponents/index)
│ │ ├── services/ # API 服务(auth/permission/role/menu/department/admin 等)
│ │ ├── store/ # 状态管理(reducers/global + store 配置)
│ │ ├── utils/ # 工具(api/request、monitor_sdk、utils 等)
│ │ ├── index.js # 前端入口
│ │ └── global.css # 全局样式
│ └── package.json # 前端项目配置
├── LICENSE # 许可证
└── README.md # 项目说明
缓存功能
- 架构:支持内存与 Redis 双实现,依据
config/cache.js的type与config/redis自动选择;Redis 使用SCAN MATCH批量清理,避免阻塞。 - 键规范:统一通过
generateCacheKey(module, resourceType, identifier, operation?)生成,例如:- 列表:
app:v1:permission:list:<filtersJson> - 单项:
app:v1:user:item:<id>、app:v1:role:item:<id> - 用户角色:
app:v1:user:roles:<userId> - 权限码:
app:v1:permission:codes:user:<userId>
- 列表:
- 模式清理:使用
getCacheKeyPattern(module, resourceType)生成模式,示例:- 清理权限列表:
clearByPattern(getCacheKeyPattern('permission','list')) - 清理角色列表:
clearByPattern(getCacheKeyPattern('role','list')) - 清理用户统计:
clearByPattern(getCacheKeyPattern('user','stats'))
- 清理权限列表:
- 读缓存位置:模型/服务层统一设置读缓存(如
withCache装饰器、cacheService.get/set),控制器层主要进行失效与聚合响应缓存。 - 失效策略:写操作完成后在控制器集中清理相关键(精确
del+ 按模块模式clearByPattern),确保响应与后端数据一致。 - 监控与日志:缓存操作由
cacheMonitor记录命中率与耗时;日志模块输出结构化信息方便排查。
示例代码(列表缓存与清理):
const {
generateCacheKey, getCacheKeyPattern } = require('./node-express-mysql/src/cache/utils/cacheKeyGenerator');
const cacheService = require('./node-express-mysql/src/cache/cacheService');
// 读取(命中则直接返回)
const cacheKey = generateCacheKey('role','list', JSON.stringify({
page, limit, filters }));
const cached = await cacheService.get(cacheKey);
// 写入(查询后写入)
await cacheService.set(cacheKey, {
data, pagination }, null, 'role.list');
// 清理(写操作后)
await cacheService.clearByPattern(getCacheKeyPattern('role','list'));
更多规范见后端文档:node-express-mysql/docs/3.缓存管理.md、node-express-mysql/docs/2.缓存键命名规范.md。
技术栈
后端
- Node.js >= 18.0.0 - JavaScript运行时
- Express.js - Web应用框架
- MySQL >= 8.0 - 关系型数据库
- JWT - JSON Web Token认证
- bcryptjs - 密码加密
- svg-captcha - 图形验证码
- express-session - 会话管理
- cors - 跨域处理
- dotenv - 环境变量管理
前端
- React 18.2.0 - UI框架
- Antd 5.26.2 - UI组件库
- Webpack 5.99.9 - 模块打包器
- Babel 7.27.4 - JavaScript编译器
- Redux Toolkit 2.8.2 - 状态管理
- React Router 6.30.0 - 路由管理
- Axios 1.10.0 - HTTP客户端
- Less 4.3.0 - CSS预处理器
- PostCSS - CSS后处理器
权限设计
该项目的权限架构采用RBAC0 + 权限层级 + 数据域来设计,相比传统的5张数据库表,多了两张数据库表,分别是权限表和角色权限关联表,以角色为核心,通过角色与菜单/权限点/数据域的关联,实现细粒度的权限控制。
四层模型
系统管理层(角色与层级)、功能模块层(菜单/模块)、操作权限层(权限点/接口/按钮)、数据权限层(部门/数据域)。
- 目标:更精细、更灵活的权限控制,满足复杂业务场景;兼容当前实现并可渐进增强。
- 用户层:
user,账号主体,绑定所属部门与基础信息。 - 角色层:
role,权限载体,聚合菜单/权限点/数据权限。 - 菜单/资源层:
menu,页面/目录/按钮(node_type)与路由/组件,含权限编码code与访问类型access_type(0-公共,1-私有)。 - 权限点/数据权限层:
permission作为操作点(接口/按钮)集合,department作为数据域;通过关联表构成角色的操作与数据范围。
数据库(7 张权限关联表)
user:用户表,含department_id等基础字段。role:角色表,含系统预置与保护标识(is_system/is_protected)。menu:菜单表,目录/菜单/按钮(node_type=1/2/3),权限编码code与路由/组件信息。permission:权限点表,定义接口/操作编码集合。user_role:用户与角色关联表(多对多)。role_menu:角色与菜单关联表(多对多),决定角色可见页面/按钮。role_permission:角色与权限点关联表(多对多),决定角色可用接口/操作。- 扩展:
department与role_data_permission(角色数据权限关联表)用于数据域授权,限定角色的数据访问范围。
关联关系
- 用户→角色:
user_role;一个用户可绑定多个角色。 - 角色→菜单:
role_menu;决定该角色在前端可见的目录/页面/按钮集合。 - 角色→权限点:
role_permission;决定该角色在后端可用的接口/操作集合。 - 角色→数据域:
role_data_permission;定义角色在不同部门/数据范围内的可访问性。
判定流程
- 后端接口权限:
- 认证中间件校验 Token 并设置
req.user。 - 路由层使用权限校验中间件(如
checkPermission('code')与等级checkPermissionLevel(40))核验权限码与安全等级。 - 权限码来源:菜单/权限表的
code,通过用户的角色聚合得到可用集合(menuModel.getUserPermissionCodes)。
- 认证中间件校验 Token 并设置
- 前端页面权限:
- 路由与菜单:后端返回的菜单按
access_type与role_menu过滤;非超级管理员补齐父级目录,保证导航完整。 - 按钮权限:
AuthButton基于权限码code控制显隐(与后端同源编码)。
- 路由与菜单:后端返回的菜单按
超级管理员
- 统一判断:
utils.isSuperAdminById(userId),依据角色code='SUPER_ADMIN'或系统预置且受保护(is_system=1 && is_protected=1)。 - 超级管理员跳过菜单与权限过滤,拥有全部资源与操作能力。
模型层
PermissionModel:获取权限列表/详情、按角色/用户获取权限码;分配角色权限(事务)、缓存permissions:role:*、permission_codes:user:*。DataPermissionModel:按角色/用户获取数据权限(部门ID集合),校验用户是否可访问某部门;生成数据权限 SQL 过滤条件。MenuModel:按用户返回菜单支持access_type过滤;非超级管理员补齐父级目录,保证导航完整;支持最小字段集与完整字段集。
中间件
checkPermission(requiredPermissions, { checkDataPermission, dataPermissionType })checkRole(requiredRoles)checkPermissionLevel(minLevel)checkDataPermission(permissionType)
路由
- 权限管理:
GET /permissions、GET /permissions/:id、GET /roles/:roleId/permissions、PUT /roles/:roleId/permissions、GET /user/permissions - 角色管理:
GET /roles、GET /roles/:id、POST /roles(层级≥20)、PUT /roles/:id、DELETE /roles/:id、GET/PUT /roles/:roleId/data-permissions
权限码规范(示例)
- 模块层:
module:{模块名}:{操作}(如module:user:view、module:role:edit) - 操作层:
{模块名}:{实体}:{操作}(如system:user:create、system:role:delete、content:article:publish)
快速开始
环境要求
- Node.js >= 18.0.0
- MySQL >= 8.0
- npm >= 8.0.0 或 yarn >= 1.22.0
1. 克隆项目
git clone <repository-url>
cd project-root
后端服务启动
# 进入后端目录
cd node-express-mysql
# 安装依赖
npm install
# 或
yarn install
# 配置环境变量
cp .env.example .env
# 编辑 .env 文件,配置数据库连接信息
# 初始化数据库
# 执行 config/sql/ 目录下的SQL文件
# 启动服务
npm run dev
# 或
yarn dev
后端服务默认 http://localhost:8888
前端应用启动
# 进入前端目录
cd react-antd-webpack
# 安装依赖
npm install
# 或
yarn install
# 启动开发服务器
npm run dev
# 或
yarn dev
前端应用默认 http://localhost:3000
配置说明
后端环境变量
创建 node-express-mysql/.env 文件:
# 数据库配置
DB_HOST=localhost
DB_PORT=3306
DB_USER=root
DB_PASSWORD=your_password
DB_NAME=your_database
# JWT 配置
JWT_SECRET=your-jwt-secret-key
REFRESH_SECRET=your-refresh-secret-key
# 会话配置
SESSION_SECRET=your-session-secret-key
# 服务器配置
PORT=8888
NODE_ENV=development
LOG_LEVEL=debug
# 单点登录开关:on 则登录时清退其他会话并通过 SSE 通知
SINGLE_LOGIN=on
前端 API 配置
修改 react-antd-webpack/src/utils/api/request.js 中的API基础URL:
const baseURL = 'http://localhost:8888';
API 接口文档
认证相关
| 接口 | 方法 | 路径 | 功能 | 权限 |
|---|---|---|---|---|
| 用户登录 | POST | /login |
用户登录 | 公开 |
| 用户登出 | POST | /auth/logout |
用户登出 | 需要token |
| 强制登出用户 | POST | /auth/logout/:userId |
强制清退 | 需要token |
| 强制登出会话 | POST | /auth/logout/session/:sessionId |
强制清退会话 | 需要token |
| 刷新Token | PATCH | /refresh |
刷新访问令牌 | 需要refresh token |
| 获取验证码 | POST | /captcha |
获取图形验证码 | 公开 |
| 健康检查 | GET | /health |
系统健康检查 | 公开 |
用户管理
| 接口 | 方法 | 路径 | 功能 | 权限 |
|---|---|---|---|---|
| 获取用户列表 | GET | /users |
获取所有用户 | 需要token |
| 获取用户信息 | GET | /users/:id |
获取指定用户 | 需要token |
| 创建用户 | POST | /users |
创建新用户 | 需要token |
| 更新用户 | PUT | /users/:id |
更新用户信息 | 需要token |
| 删除用户 | DELETE | /users/:id |
删除用户 | 需要token |
角色管理
| 接口 | 方法 | 路径 | 功能 | 权限 |
|---|---|---|---|---|
| 获取角色列表 | GET | /roles |
获取所有角色 | 需要token |
| 创建角色 | POST | /roles |
创建新角色 | 需要token |
| 更新角色 | PUT | /roles/:id |
更新角色信息 | 需要token |
| 删除角色 | DELETE | /roles/:id |
删除角色 | 需要token |
| 绑定菜单 | POST | /roles/bind-menus |
角色绑定菜单 | 需要token |
菜单管理
| 接口 | 方法 | 路径 | 功能 | 权限 |
|---|---|---|---|---|
| 获取菜单列表 | GET | /menus |
获取所有菜单 | 需要token |
| 创建菜单 | POST | /menus |
创建新菜单 | 需要token |
| 更新菜单 | PUT | /menus/:id |
更新菜单信息 | 需要token |
| 删除菜单 | DELETE | /menus/:id |
删除菜单 | 需要token |
审计日志与在线用户
| 接口 | 方法 | 路径 | 功能 |
|---|---|---|---|
| 审计列表 | GET | /api/admin/audit/logs |
审计日志分页查询 |
| 审计详情 | GET | /api/admin/audit/log/:id |
审计日志详情 |
| 在线用户 | GET | /api/admin/audit/online/users |
基于审计窗口聚合在线用户 |
返回字段:user_id/username/dept_id/dept_name/last_active_time/actions_in_window/last_url/last_method/client_ip/user_agent/browser/operating_system/location/change_summary/session_id/session_last_active_time/session_duration_minutes。
SSE 实时通知
| 接口 | 方法 | 路径 | 功能 |
|---|---|---|---|
| 认证连接 | GET | /sse/connect/auth |
建立 SSE 连接(需 Authorization) |
| 发送消息 | POST | /sse/send |
向指定用户发送通知 |
| 广播消息 | POST | /sse/broadcast |
向所有连接广播 |
| 连接统计 | GET | /sse/stats |
查看连接统计 |
连接建议附带稳定 clientId:请求头 X-Client-Id 与 URL ?clientId=<id>。服务端在 open/welcome 事件返回 { connectionId, clientId }。
前端特性
动态权限路由
- 动态路由注册 - 根据后端返回的菜单数据动态注册路由
- 权限控制 - 基于RBAC模型的页面级权限控制
- 按钮权限 - 支持按钮级别的权限控制
- 路由守卫 - 自动处理未授权访问和登录失效
状态管理
- Redux Toolkit - 现代化的状态管理方案
- 持久化存储 - 用户信息和菜单数据本地缓存
- 无感刷新 - 自动处理Token过期和刷新
错误处理
- 全局错误捕获 - ErrorBoundary + 全局错误监听
- 错误去重 - 防止重复错误上报
- 友好降级 - 错误页面自动跳转到有效页面
性能优化
- 代码分割 - 路由级别的懒加载
- 资源优化 - 图片压缩和CDN支持
- 缓存策略 - 合理的缓存机制
安全特性
认证安全
- JWT双Token - Access Token + Refresh Token机制
- Token过期 - 访问令牌1小时过期,刷新令牌7天过期
- 自动清理 - 定时清理过期和已撤销的token
- 强制登出 - 支持强制登出用户所有设备
输入验证
- 参数验证 - 所有接口都有完整的参数验证
- 格式检查 - 验证ID、邮箱、手机号等格式
- 重复性检查 - 防止创建重复的用户名、角色编码等
- SQL注入防护 - 使用参数化查询防止SQL注入
验证码保护
- 图形验证码 - 使用svg-captcha生成验证码
- 内存存储 - 验证码存储在服务器端内存中
- 过期机制 - 验证码5分钟自动过期
- 一次性使用 - 验证码使用后自动清除
响应格式
成功响应
{
"success": true,
"code": 200,
"message": "操作成功",
"data": {
"id": 1,
"username": "admin",
"name": "管理员"
},
"timestamp": "2024-01-01T12:00:00.000Z"
}
错误响应
{
"success": false,
"code": 400,
"message": "请求参数错误",
"data": null,
"timestamp": "2024-01-01T12:00:00.000Z"
}
开发调试
后端调试
# 查看验证码状态
curl -H "Authorization: Bearer <token>" \
http://localhost:8888/captcha/status
# 手动清理过期token
curl -X POST -H "Authorization: Bearer <token>" \
http://localhost:8888/cleanup-tokens
# 获取token统计信息
curl -H "Authorization: Bearer <token>" \
http://localhost:8888/token-stats
前端调试
- Redux DevTools - 状态管理调试
- React DevTools - 组件调试
- Network面板 - API请求调试
- Console日志 - 错误信息查看
部署指南
生产环境部署
本项目提供多种部署方式,包括传统部署、Docker部署和Docker Compose部署。
方式一:传统部署
后端部署
# 1. 进入后端目录
cd node-express-mysql
# 2. 安装依赖
npm install
# 或
yarn install
# 3. 设置环境变量
export NODE_ENV=production
export DB_HOST=your-production-db-host
export DB_PASSWORD=your-production-password
export JWT_SECRET=your-production-jwt-secret
# 4. 安装PM2进程管理器
npm install -g pm2
# 5. 启动应用
pm2 start index.js --name "backend-api"
# 6. 设置开机自启
pm2 startup
pm2 save
前端部署
# 1. 进入前端目录
cd react-antd-webpack
# 2. 安装依赖
npm install
# 或
yarn install
# 3. 构建生产版本
npm run build
# 或
yarn build
# 4. 部署到Web服务器
# 将dist目录内容上传到Web服务器
# 配置Nginx反向代理
方式二:Docker Compose部署(推荐)
项目已包含完整的Docker Compose配置,支持一键部署。
1. 环境准备
创建环境变量文件 docker-compose/.env:
# MySQL数据库配置
MYSQL_ROOT_PASSWORD=your_secure_password
MYSQL_DATABASE=your_database_name
MYSQL_USER=your_database_user
MYSQL_PASSWORD=your_database_password
# 时区设置
TZ=Asia/Shanghai
LANG=en_US.UTF-8
2. 快速启动
# 进入项目根目录
cd project-root
# 进入docker-compose目录
cd docker-compose
# 启动所有服务
docker-compose up -d
# 查看服务状态
docker-compose ps
# 查看日志
docker-compose logs -f
# 停止服务
docker-compose down
3. 服务说明
当前Docker Compose配置包含以下服务:
- MySQL 8.0.34 - 数据库服务(端口:3306)
- Nginx 1.25.2 - 静态资源服务(端口:8080)
4. 数据持久化
- 数据库数据:
./docker-compose/db-data/data - 数据库配置:
./docker-compose/db-data/conf - 数据库日志:
./docker-compose/db-data/logs - Nginx日志:
./docker-compose/nginx/log
5. 访问服务
- Nginx静态服务:http://localhost:8080
- MySQL数据库:localhost:3306
方式三:完整Docker部署
1. 创建Dockerfile
后端Dockerfile (node-express-mysql/Dockerfile):
FROM node:18-alpine
# 设置工作目录
WORKDIR /app
# 复制package文件
COPY package*.json ./
COPY yarn.lock ./
# 安装依赖
RUN yarn install --frozen-lockfile
# 复制源代码
COPY . .
# 暴露端口
EXPOSE 8888
# 启动命令
CMD ["npm", "start"]
前端Dockerfile (react-antd-webpack/Dockerfile):
FROM node:18-alpine as builder
# 设置工作目录
WORKDIR /app
# 复制package文件
COPY package*.json ./
COPY yarn.lock ./
# 安装依赖
RUN yarn install --frozen-lockfile
# 复制源代码
COPY . .
# 构建应用
RUN yarn build
# 生产阶段
FROM nginx:1.25.2-alpine
# 复制构建文件
COPY --from=builder /app/dist /usr/share/nginx/html
# 复制nginx配置
COPY nginx.conf /etc/nginx/conf.d/default.conf
# 暴露端口
EXPOSE 80
# 启动nginx
CMD ["nginx", "-g", "daemon off;"]
2. 完整Docker Compose配置
创建 docker-compose-full.yml:
version: '3.8'
services:
mysql:
image: mysql:8.0.34
container_name: mysql-8
restart: always
environment:
TZ: Asia/Shanghai
MYSQL_ROOT_PASSWORD: ${
MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${
MYSQL_DATABASE}
MYSQL_USER: ${
MYSQL_USER}
MYSQL_PASSWORD: ${
MYSQL_PASSWORD}
ports:
- "3306:3306"
volumes:
- ./docker-compose/db-data/data:/var/lib/mysql
- ./docker-compose/db-data/conf:/etc/mysql/conf.d
- ./docker-compose/db-data/logs:/var/log/mysql
networks:
- app-network
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
backend:
build: ./node-express-mysql
container_name: backend-api
restart: always
ports:
- "8888:8888"
environment:
- NODE_ENV=production
- DB_HOST=mysql
- DB_PORT=3306
- DB_USER=${
MYSQL_USER}
- DB_PASSWORD=${
MYSQL_PASSWORD}
- DB_NAME=${
MYSQL_DATABASE}
- JWT_SECRET=${
JWT_SECRET}
- REFRESH_SECRET=${
REFRESH_SECRET}
depends_on:
- mysql
networks:
- app-network
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
frontend:
build: ./react-antd-webpack
container_name: frontend-app
restart: always
ports:
- "80:80"
depends_on:
- backend
networks:
- app-network
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
networks:
app-network:
driver: bridge
3. 部署步骤
# 1. 克隆项目
git clone <repository-url>
cd project-root
# 2. 创建环境变量文件
cat > .env << EOF
MYSQL_ROOT_PASSWORD=your_secure_password
MYSQL_DATABASE=your_database_name
MYSQL_USER=your_database_user
MYSQL_PASSWORD=your_database_password
JWT_SECRET=your_jwt_secret_key
REFRESH_SECRET=your_refresh_secret_key
EOF
# 3. 启动完整服务
docker-compose -f docker-compose-full.yml up -d
# 4. 初始化数据库
# 执行 node-express-mysql/config/sql/ 目录下的SQL文件
# 5. 访问应用
# 前端:http://localhost
# 后端:http://localhost:8888
方式四:生产环境优化部署
1. 生产环境Docker Compose配置
创建 docker-compose-prod.yml:
version: '3.8'
services:
mysql:
image: mysql:8.0.34
restart: always
environment:
TZ: Asia/Shanghai
MYSQL_ROOT_PASSWORD: ${
MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${
MYSQL_DATABASE}
MYSQL_USER: ${
MYSQL_USER}
MYSQL_PASSWORD: ${
MYSQL_PASSWORD}
volumes:
- mysql-data:/var/lib/mysql
- ./docker-compose/db-data/conf:/etc/mysql/conf.d
networks:
- app-network
deploy:
resources:
limits:
memory: 1G
reservations:
memory: 512M
logging:
driver: json-file
options:
max-size: "50m"
max-file: "5"
backend:
build: ./node-express-mysql
restart: always
environment:
- NODE_ENV=production
- DB_HOST=mysql
- DB_USER=${
MYSQL_USER}
- DB_PASSWORD=${
MYSQL_PASSWORD}
- DB_NAME=${
MYSQL_DATABASE}
- JWT_SECRET=${
JWT_SECRET}
- REFRESH_SECRET=${
REFRESH_SECRET}
depends_on:
- mysql
networks:
- app-network
deploy:
replicas: 2
resources:
limits:
memory: 512M
reservations:
memory: 256M
logging:
driver: json-file
options:
max-size: "50m"
max-file: "5"
frontend:
build: ./react-antd-webpack
restart: always
depends_on:
- backend
networks:
- app-network
deploy:
resources:
limits:
memory: 256M
reservations:
memory: 128M
logging:
driver: json-file
options:
max-size: "50m"
max-file: "5"
volumes:
mysql-data:
networks:
app-network:
driver: bridge
2. 生产环境部署脚本
创建 deploy.sh:
#!/bin/bash
# 生产环境部署脚本
set -e
echo "🚀 开始生产环境部署..."
# 检查Docker是否安装
if ! command -v docker &> /dev/null; then
echo "❌ Docker未安装,请先安装Docker"
exit 1
fi
# 检查Docker Compose是否安装
if ! command -v docker-compose &> /dev/null; then
echo "❌ Docker Compose未安装,请先安装Docker Compose"
exit 1
fi
# 检查环境变量文件
if [ ! -f .env ]; then
echo "❌ 环境变量文件.env不存在,请创建"
exit 1
fi
# 构建前端
echo "📦 构建前端应用..."
cd react-antd-webpack
npm run build
cd ..
# 停止现有服务
echo "🛑 停止现有服务..."
docker-compose -f docker-compose-prod.yml down
# 启动服务
echo "🚀 启动生产服务..."
docker-compose -f docker-compose-prod.yml up -d
# 等待服务启动
echo "⏳ 等待服务启动..."
sleep 30
# 检查服务状态
echo "🔍 检查服务状态..."
docker-compose -f docker-compose-prod.yml ps
echo "✅ 生产环境部署完成!"
echo "🌐 前端访问地址: http://localhost"
echo "🔧 后端API地址: http://localhost:8888"
3. 监控和日志
# 查看服务状态
docker-compose -f docker-compose-prod.yml ps
# 查看实时日志
docker-compose -f docker-compose-prod.yml logs -f
# 查看特定服务日志
docker-compose -f docker-compose-prod.yml logs -f backend
# 进入容器调试
docker exec -it backend-api /bin/sh
docker exec -it mysql-8 mysql -u root -p
# 查看资源使用情况
docker stats
常用Docker命令
# 查看容器状态
docker ps -a
# 查看容器日志
docker logs -f container_name
# 进入容器
docker exec -it container_name /bin/sh
# 停止容器
docker stop container_name
# 删除容器
docker rm container_name
# 查看镜像
docker images
# 删除镜像
docker rmi image_name
# 清理未使用的资源
docker system prune -a
# 查看Docker Compose服务
docker-compose ps
# 重启服务
docker-compose restart service_name
# 更新服务
docker-compose up -d --force-recreate service_name
生产环境注意事项
安全配置
- 使用强密码
- 定期更新密钥
- 限制网络访问
- 启用SSL/TLS
性能优化
- 配置数据库连接池
- 启用Redis缓存
- 使用CDN加速
- 配置负载均衡
监控告警
- 设置服务监控
- 配置日志收集
- 设置告警通知
- 定期备份数据
备份策略
- 数据库定期备份
- 配置文件版本控制
- 镜像定期更新
- 灾难恢复预案
📈 性能优化
后端优化
- 数据库索引 - 为查询字段添加适当索引
- 连接池 - 使用数据库连接池
- 缓存策略 - Redis缓存热点数据
- 压缩中间件 - 启用gzip压缩
前端优化
- 代码分割 - 路由级别的代码分割
- 懒加载 - 组件和路由懒加载
- 资源压缩 - 图片和静态资源压缩
- CDN加速 - 静态资源CDN部署
🤝 贡献指南
- Fork 本仓库
- 创建特性分支 (
git checkout -b feature/AmazingFeature) - 提交更改 (
git commit -m 'Add some AmazingFeature') - 推送到分支 (
git push origin feature/AmazingFeature) - 打开 Pull Request
📄 许可证
本项目采用 MIT 许可证 - 查看 LICENSE 文件了解详情
👨💻 作者
- lyq - 项目创建者和维护者 - lyqjob@yeah.net
🙏 致谢
⭐ 如果这个项目对你有帮助,请给它一个星标!