前言
一直苦於技術沒有接觸後端,導致技術不夠全面。離職後休息這段時間,設計架構了前後端系統,從另一個層面來講,確實邁進了一大步,遇見了之前從未遇到的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
🙏 致謝
⭐ 如果這個項目對你有幫助,請給它一個星標!