Files
你的用户名 237c7802e5
Some checks failed
Deploy / deploy (push) Has been cancelled
Initial commit: Telegram Management System
Full-stack web application for Telegram management
- Frontend: Vue 3 + Vben Admin
- Backend: NestJS
- Features: User management, group broadcast, statistics

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 15:37:50 +08:00

2805 lines
56 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Telegram 管理系统部署指南
> **版本**: v2.0.0
> **更新时间**: 2024-01-20
> **维护者**: 开发团队
## 📋 文档目录
- [部署概述](#部署概述)
- [环境要求](#环境要求)
- [快速部署](#快速部署)
- [开发环境部署](#开发环境部署)
- [生产环境部署](#生产环境部署)
- [Docker部署](#docker部署)
- [Kubernetes部署](#kubernetes部署)
- [数据库配置](#数据库配置)
- [环境变量配置](#环境变量配置)
- [SSL证书配置](#ssl证书配置)
- [监控与日志](#监控与日志)
- [备份与恢复](#备份与恢复)
- [故障排除](#故障排除)
---
## 🏗️ 部署概述
### 系统架构
Telegram管理系统采用前后端分离架构包含以下组件
- **前端应用**: Vue 3 + Vben Admin
- **后端API**: Node.js + Express
- **数据库**: MySQL + Redis + MongoDB
- **反向代理**: Nginx
- **实时通信**: WebSocket
### 部署方式
支持多种部署方式:
1. **Docker Compose**: 快速本地部署和开发
2. **Kubernetes**: 生产环境容器编排
3. **传统部署**: 直接在服务器上安装
4. **云原生部署**: 支持AWS、阿里云等云平台
---
## 💻 环境要求
### 硬件要求
| 环境 | CPU | 内存 | 存储 | 网络 |
| ---------- | ---- | ---- | ----- | ------- |
| 开发环境 | 2核 | 4GB | 20GB | 10Mbps |
| 测试环境 | 4核 | 8GB | 100GB | 50Mbps |
| 生产环境 | 8核 | 16GB | 500GB | 100Mbps |
| 高可用环境 | 16核 | 32GB | 1TB | 1Gbps |
### 软件要求
#### 基础软件
| 软件 | 版本要求 | 说明 |
| -------------- | -------- | ---------- |
| Node.js | ≥18.0.0 | 运行时环境 |
| npm/pnpm | ≥8.0.0 | 包管理器 |
| Git | ≥2.30.0 | 版本控制 |
| Docker | ≥20.10.0 | 容器运行时 |
| Docker Compose | ≥2.0.0 | 容器编排 |
#### 数据库
| 数据库 | 版本要求 | 用途 |
| ------- | -------- | ---------- |
| MySQL | ≥8.0.0 | 主数据存储 |
| Redis | ≥7.0.0 | 缓存和会话 |
| MongoDB | ≥6.0.0 | 日志存储 |
#### Web服务器
| 服务器 | 版本要求 | 用途 |
| ------ | -------- | ------------- |
| Nginx | ≥1.20.0 | 反向代理 |
| Apache | ≥2.4.0 | 备选web服务器 |
### 网络要求
- **入站端口**: 80 (HTTP), 443 (HTTPS), 3000 (API)
- **出站访问**: 访问Telegram API、邮件服务、短信服务
- **内部通信**: 各服务间网络连通性
---
## ⚡ 快速部署
### 使用Docker Compose推荐
1. **克隆项目**
```bash
git clone https://github.com/your-org/telegram-management-system.git
cd telegram-management-system
```
2. **配置环境变量**
```bash
cp .env.example .env
# 编辑 .env 文件,配置必要的环境变量
```
3. **启动所有服务**
```bash
docker-compose up -d
```
4. **初始化数据库**
```bash
docker-compose exec backend npm run db:migrate
docker-compose exec backend npm run db:seed
```
5. **访问系统**
- 前端地址: http://localhost
- API地址: http://localhost:3000
- 默认账号: admin / 111111
### 一键安装脚本
提供快速安装脚本:
```bash
# 下载并执行安装脚本
curl -fsSL https://raw.githubusercontent.com/your-org/telegram-management-system/main/scripts/install.sh | bash
# 或者下载后执行
wget https://raw.githubusercontent.com/your-org/telegram-management-system/main/scripts/install.sh
chmod +x install.sh
./install.sh
```
---
## 🔧 开发环境部署
### 前端开发环境
1. **安装依赖**
```bash
cd frontend-vben/apps/web-antd
pnpm install
```
2. **配置开发环境**
```bash
# 复制环境配置文件
cp .env.development.example .env.development
# 编辑配置文件
nano .env.development
```
```env
# .env.development
VITE_API_URL=http://localhost:3001/api/v1
VITE_WS_URL=ws://localhost:3001/ws
VITE_APP_TITLE=Telegram管理系统(开发)
```
3. **启动开发服务器**
```bash
pnpm dev
```
### 后端开发环境
1. **安装依赖**
```bash
cd backend
npm install
```
2. **配置数据库**
```bash
# 启动MySQL (使用Docker)
docker run -d --name mysql-dev \
-e MYSQL_ROOT_PASSWORD=root123 \
-e MYSQL_DATABASE=telegram_system \
-e MYSQL_USER=app_user \
-e MYSQL_PASSWORD=app_password \
-p 3306:3306 \
mysql:8.0
# 启动Redis
docker run -d --name redis-dev \
-p 6379:6379 \
redis:7-alpine
# 启动MongoDB
docker run -d --name mongodb-dev \
-p 27017:27017 \
mongo:6.0
```
3. **配置环境变量**
```bash
cp .env.example .env.development
```
```env
# .env.development
NODE_ENV=development
PORT=3001
# 数据库配置
DB_HOST=localhost
DB_PORT=3306
DB_NAME=telegram_system
DB_USER=app_user
DB_PASSWORD=app_password
# Redis配置
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=
# MongoDB配置
MONGODB_URI=mongodb://localhost:27017/telegram_system_logs
# JWT配置
JWT_SECRET=your-jwt-secret-key
JWT_EXPIRE=7d
REFRESH_TOKEN_EXPIRE=30d
# Telegram配置
TELEGRAM_BOT_TOKEN=your-telegram-bot-token
TELEGRAM_WEBHOOK_URL=https://your-domain.com/webhook/telegram
```
4. **初始化数据库**
```bash
# 运行数据库迁移
npm run db:migrate
# 填充初始数据
npm run db:seed
```
5. **启动开发服务器**
```bash
npm run dev
```
### 开发环境验证
验证开发环境是否正常:
```bash
# 检查前端
curl http://localhost:5173
# 检查后端API
curl http://localhost:3001/api/v1/health
# 检查数据库连接
npm run db:check
```
---
## 🏭 生产环境部署
### 服务器准备
1. **系统要求**
```bash
# Ubuntu 20.04 LTS 或更高版本
lsb_release -a
# 安装基础软件
sudo apt update
sudo apt install -y curl wget git nginx certbot
```
2. **安装Node.js**
```bash
# 安装Node.js 18.x
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs
# 验证安装
node --version
npm --version
```
3. **安装Docker**
```bash
# 安装Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# 安装Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# 验证安装
docker --version
docker-compose --version
```
### 应用部署
1. **克隆代码**
```bash
sudo mkdir -p /opt/telegram-system
sudo chown $USER:$USER /opt/telegram-system
cd /opt/telegram-system
git clone https://github.com/your-org/telegram-management-system.git .
```
2. **构建前端**
```bash
cd frontend-vben/apps/web-antd
# 安装pnpm
npm install -g pnpm
# 安装依赖
pnpm install
# 构建生产版本
pnpm build
```
3. **配置生产环境变量**
```bash
cp .env.example .env.production
```
```env
# .env.production
NODE_ENV=production
PORT=3001
# 数据库配置
DB_HOST=mysql
DB_PORT=3306
DB_NAME=telegram_system
DB_USER=app_user
DB_PASSWORD=your-secure-password
# Redis配置
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=your-redis-password
# MongoDB配置
MONGODB_URI=mongodb://mongodb:27017/telegram_system_logs
# JWT配置
JWT_SECRET=your-very-secure-jwt-secret-key
JWT_EXPIRE=7d
REFRESH_TOKEN_EXPIRE=30d
# Telegram配置
TELEGRAM_BOT_TOKEN=your-telegram-bot-token
TELEGRAM_WEBHOOK_URL=https://yourdomain.com/webhook/telegram
# 安全配置
CORS_ORIGINS=https://yourdomain.com
RATE_LIMIT_MAX=100
RATE_LIMIT_WINDOW=60000
# 邮件配置
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your-email@gmail.com
SMTP_PASS=your-app-password
# 文件存储
FILE_STORAGE_TYPE=local
FILE_STORAGE_PATH=/app/uploads
MAX_FILE_SIZE=10485760
# 日志配置
LOG_LEVEL=info
LOG_FILE_PATH=/app/logs/app.log
```
4. **配置Docker Compose**
```yaml
# docker-compose.prod.yml
version: '3.8'
services:
frontend:
build:
context: ./frontend-vben/apps/web-antd
dockerfile: Dockerfile.prod
container_name: telegram-frontend
restart: unless-stopped
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./ssl:/etc/nginx/ssl:ro
ports:
- '80:80'
- '443:443'
depends_on:
- backend
networks:
- telegram-network
backend:
build:
context: ./backend
dockerfile: Dockerfile.prod
container_name: telegram-backend
restart: unless-stopped
env_file:
- .env.production
volumes:
- ./uploads:/app/uploads
- ./logs:/app/logs
ports:
- '3001:3001'
depends_on:
- mysql
- redis
- mongodb
networks:
- telegram-network
healthcheck:
test: ['CMD', 'curl', '-f', 'http://localhost:3001/health']
interval: 30s
timeout: 10s
retries: 3
mysql:
image: mysql:8.0
container_name: telegram-mysql
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
MYSQL_DATABASE: ${DB_NAME}
MYSQL_USER: ${DB_USER}
MYSQL_PASSWORD: ${DB_PASSWORD}
volumes:
- mysql_data:/var/lib/mysql
- ./sql/init:/docker-entrypoint-initdb.d
ports:
- '3306:3306'
networks:
- telegram-network
command: --default-authentication-plugin=mysql_native_password
redis:
image: redis:7-alpine
container_name: telegram-redis
restart: unless-stopped
command: redis-server --requirepass ${REDIS_PASSWORD} --appendonly yes
volumes:
- redis_data:/data
ports:
- '6379:6379'
networks:
- telegram-network
mongodb:
image: mongo:6.0
container_name: telegram-mongodb
restart: unless-stopped
environment:
MONGO_INITDB_ROOT_USERNAME: ${MONGO_ROOT_USER}
MONGO_INITDB_ROOT_PASSWORD: ${MONGO_ROOT_PASSWORD}
volumes:
- mongodb_data:/data/db
ports:
- '27017:27017'
networks:
- telegram-network
volumes:
mysql_data:
driver: local
redis_data:
driver: local
mongodb_data:
driver: local
networks:
telegram-network:
driver: bridge
```
5. **启动生产服务**
```bash
# 构建并启动所有服务
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
```
---
## 🐳 Docker部署
### Dockerfile配置
#### 前端Dockerfile
```dockerfile
# frontend-vben/apps/web-antd/Dockerfile.prod
FROM node:18-alpine AS builder
WORKDIR /app
# 复制package文件
COPY package*.json ./
COPY pnpm-lock.yaml ./
# 安装pnpm和依赖
RUN npm install -g pnpm
RUN pnpm install --frozen-lockfile
# 复制源码
COPY . .
# 构建应用
RUN pnpm build
# 生产阶段
FROM nginx:alpine
# 复制构建产物
COPY --from=builder /app/dist /usr/share/nginx/html
# 复制nginx配置
COPY nginx.conf /etc/nginx/nginx.conf
# 创建必要目录
RUN mkdir -p /var/log/nginx
# 暴露端口
EXPOSE 80 443
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost/ || exit 1
CMD ["nginx", "-g", "daemon off;"]
```
#### 后端Dockerfile
```dockerfile
# backend/Dockerfile.prod
FROM node:18-alpine
# 设置工作目录
WORKDIR /app
# 创建非root用户
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nodejs -u 1001
# 复制package文件
COPY package*.json ./
# 安装生产依赖
RUN npm install --only=production && npm cache clean --force
# 复制源码
COPY . .
# 创建必要目录
RUN mkdir -p uploads logs
RUN chown -R nodejs:nodejs /app
# 切换到非root用户
USER nodejs
# 暴露端口
EXPOSE 3001
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3001/health || exit 1
# 启动应用
CMD ["node", "server.js"]
```
### Docker构建优化
1. **多阶段构建**
```dockerfile
# 使用多阶段构建减少镜像大小
FROM node:18-alpine AS dependencies
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
FROM node:18-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:18-alpine AS runtime
WORKDIR /app
COPY --from=dependencies /app/node_modules ./node_modules
COPY --from=build /app/dist ./dist
COPY package*.json ./
EXPOSE 3001
CMD ["node", "dist/server.js"]
```
2. **.dockerignore文件**
```dockerignore
# .dockerignore
node_modules
npm-debug.log
.git
.gitignore
README.md
.env.development
.env.local
coverage
.coverage
.nyc_output
.DS_Store
*.log
logs
```
### Docker网络配置
```bash
# 创建自定义网络
docker network create telegram-network
# 运行数据库服务
docker run -d --name mysql \
--network telegram-network \
-e MYSQL_ROOT_PASSWORD=root123 \
-e MYSQL_DATABASE=telegram_system \
-v mysql_data:/var/lib/mysql \
mysql:8.0
# 运行Redis
docker run -d --name redis \
--network telegram-network \
-v redis_data:/data \
redis:7-alpine
# 运行应用
docker run -d --name telegram-backend \
--network telegram-network \
-p 3001:3001 \
-e DB_HOST=mysql \
-e REDIS_HOST=redis \
telegram-system/backend:latest
```
---
## ☸️ Kubernetes部署
### 命名空间配置
```yaml
# k8s/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: telegram-system
labels:
name: telegram-system
```
### ConfigMap配置
```yaml
# k8s/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: telegram-config
namespace: telegram-system
data:
NODE_ENV: 'production'
DB_HOST: 'mysql-service'
DB_PORT: '3306'
DB_NAME: 'telegram_system'
REDIS_HOST: 'redis-service'
REDIS_PORT: '6379'
MONGODB_URI: 'mongodb://mongodb-service:27017/telegram_system_logs'
LOG_LEVEL: 'info'
```
### Secret配置
```yaml
# k8s/secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: telegram-secret
namespace: telegram-system
type: Opaque
data:
DB_PASSWORD: <base64-encoded-password>
REDIS_PASSWORD: <base64-encoded-password>
JWT_SECRET: <base64-encoded-jwt-secret>
TELEGRAM_BOT_TOKEN: <base64-encoded-bot-token>
```
### MySQL部署
```yaml
# k8s/mysql-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
namespace: telegram-system
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: telegram-secret
key: DB_PASSWORD
- name: MYSQL_DATABASE
valueFrom:
configMapKeyRef:
name: telegram-config
key: DB_NAME
volumeMounts:
- name: mysql-storage
mountPath: /var/lib/mysql
resources:
requests:
memory: '1Gi'
cpu: '500m'
limits:
memory: '2Gi'
cpu: '1000m'
volumes:
- name: mysql-storage
persistentVolumeClaim:
claimName: mysql-pvc
---
apiVersion: v1
kind: Service
metadata:
name: mysql-service
namespace: telegram-system
spec:
selector:
app: mysql
ports:
- port: 3306
targetPort: 3306
type: ClusterIP
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
namespace: telegram-system
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
```
### Redis部署
```yaml
# k8s/redis-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
namespace: telegram-system
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:7-alpine
ports:
- containerPort: 6379
command:
- redis-server
- --requirepass
- $(REDIS_PASSWORD)
- --appendonly
- 'yes'
env:
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: telegram-secret
key: REDIS_PASSWORD
volumeMounts:
- name: redis-storage
mountPath: /data
resources:
requests:
memory: '256Mi'
cpu: '250m'
limits:
memory: '512Mi'
cpu: '500m'
volumes:
- name: redis-storage
persistentVolumeClaim:
claimName: redis-pvc
---
apiVersion: v1
kind: Service
metadata:
name: redis-service
namespace: telegram-system
spec:
selector:
app: redis
ports:
- port: 6379
targetPort: 6379
type: ClusterIP
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: redis-pvc
namespace: telegram-system
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
```
### 后端应用部署
```yaml
# k8s/backend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
namespace: telegram-system
spec:
replicas: 3
selector:
matchLabels:
app: backend
template:
metadata:
labels:
app: backend
spec:
containers:
- name: backend
image: telegram-system/backend:latest
ports:
- containerPort: 3001
envFrom:
- configMapRef:
name: telegram-config
- secretRef:
name: telegram-secret
volumeMounts:
- name: uploads-storage
mountPath: /app/uploads
- name: logs-storage
mountPath: /app/logs
livenessProbe:
httpGet:
path: /health
port: 3001
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 3001
initialDelaySeconds: 5
periodSeconds: 5
resources:
requests:
memory: '512Mi'
cpu: '250m'
limits:
memory: '1Gi'
cpu: '500m'
volumes:
- name: uploads-storage
persistentVolumeClaim:
claimName: uploads-pvc
- name: logs-storage
persistentVolumeClaim:
claimName: logs-pvc
---
apiVersion: v1
kind: Service
metadata:
name: backend-service
namespace: telegram-system
spec:
selector:
app: backend
ports:
- port: 3001
targetPort: 3001
type: ClusterIP
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: uploads-pvc
namespace: telegram-system
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: logs-pvc
namespace: telegram-system
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 2Gi
```
### 前端应用部署
```yaml
# k8s/frontend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
namespace: telegram-system
spec:
replicas: 3
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: frontend
image: telegram-system/frontend:latest
ports:
- containerPort: 80
resources:
requests:
memory: '128Mi'
cpu: '100m'
limits:
memory: '256Mi'
cpu: '200m'
---
apiVersion: v1
kind: Service
metadata:
name: frontend-service
namespace: telegram-system
spec:
selector:
app: frontend
ports:
- port: 80
targetPort: 80
type: LoadBalancer
```
### Ingress配置
```yaml
# k8s/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: telegram-ingress
namespace: telegram-system
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/ssl-redirect: 'true'
nginx.ingress.kubernetes.io/proxy-body-size: '50m'
spec:
tls:
- hosts:
- yourdomain.com
- api.yourdomain.com
secretName: telegram-tls
rules:
- host: yourdomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80
- host: api.yourdomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: backend-service
port:
number: 3001
```
### 部署命令
```bash
# 创建命名空间
kubectl apply -f k8s/namespace.yaml
# 创建配置
kubectl apply -f k8s/configmap.yaml
kubectl apply -f k8s/secret.yaml
# 部署数据库
kubectl apply -f k8s/mysql-deployment.yaml
kubectl apply -f k8s/redis-deployment.yaml
# 等待数据库就绪
kubectl wait --for=condition=ready pod -l app=mysql -n telegram-system --timeout=300s
kubectl wait --for=condition=ready pod -l app=redis -n telegram-system --timeout=300s
# 部署应用
kubectl apply -f k8s/backend-deployment.yaml
kubectl apply -f k8s/frontend-deployment.yaml
# 配置Ingress
kubectl apply -f k8s/ingress.yaml
# 检查部署状态
kubectl get pods -n telegram-system
kubectl get services -n telegram-system
kubectl get ingress -n telegram-system
```
---
## 🗄️ 数据库配置
### MySQL配置
1. **创建数据库和用户**
```sql
-- 连接到MySQL
mysql -u root -p
-- 创建数据库
CREATE DATABASE telegram_system CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 创建用户
CREATE USER 'app_user'@'%' IDENTIFIED BY 'your_secure_password';
-- 授权
GRANT ALL PRIVILEGES ON telegram_system.* TO 'app_user'@'%';
FLUSH PRIVILEGES;
-- 验证
SHOW DATABASES;
SELECT User, Host FROM mysql.user WHERE User = 'app_user';
```
2. **MySQL配置优化**
```ini
# /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
# 基础配置
port = 3306
bind-address = 0.0.0.0
socket = /var/run/mysqld/mysqld.sock
# 字符集配置
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
# 内存配置
innodb_buffer_pool_size = 1G
innodb_log_file_size = 256M
key_buffer_size = 128M
max_connections = 500
# 性能配置
innodb_flush_log_at_trx_commit = 2
sync_binlog = 0
query_cache_size = 0
query_cache_type = 0
# 日志配置
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2
# 二进制日志
log-bin = mysql-bin
binlog_format = ROW
expire_logs_days = 7
```
3. **数据库初始化脚本**
```sql
-- sql/init/01-schema.sql
-- 用户表
CREATE TABLE users (
id VARCHAR(36) PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
profile JSON,
status ENUM('active', 'inactive', 'suspended') DEFAULT 'active',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_username (username),
INDEX idx_email (email),
INDEX idx_status (status)
);
-- Telegram账号表
CREATE TABLE telegram_accounts (
id VARCHAR(36) PRIMARY KEY,
telegram_id VARCHAR(20) UNIQUE NOT NULL,
username VARCHAR(50),
first_name VARCHAR(50),
last_name VARCHAR(50),
phone VARCHAR(20),
status ENUM('active', 'inactive', 'blocked') DEFAULT 'active',
metadata JSON,
managed_by VARCHAR(36),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_telegram_id (telegram_id),
INDEX idx_username (username),
INDEX idx_managed_by (managed_by),
FOREIGN KEY (managed_by) REFERENCES users(id)
);
-- 更多表定义...
```
### Redis配置
1. **Redis配置文件**
```conf
# redis.conf
port 6379
bind 0.0.0.0
requirepass your_redis_password
# 持久化配置
save 900 1
save 300 10
save 60 10000
appendonly yes
appendfsync everysec
# 内存配置
maxmemory 512mb
maxmemory-policy allkeys-lru
# 网络配置
timeout 300
keepalive 60
# 日志配置
loglevel notice
logfile /var/log/redis/redis-server.log
# 安全配置
protected-mode yes
```
2. **Redis集群配置可选**
```conf
# redis-cluster.conf
port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
```
### MongoDB配置
1. **MongoDB初始化**
```javascript
// mongo-init.js
db = db.getSiblingDB('telegram_system_logs');
// 创建用户
db.createUser({
user: 'app_user',
pwd: 'your_mongodb_password',
roles: [
{
role: 'readWrite',
db: 'telegram_system_logs',
},
],
});
// 创建索引
db.logs.createIndex({ timestamp: 1 });
db.logs.createIndex({ level: 1 });
db.logs.createIndex({ source: 1 });
db.logs.createIndex({ userId: 1 });
// 创建TTL索引日志保留30天
db.logs.createIndex({ timestamp: 1 }, { expireAfterSeconds: 2592000 });
```
2. **MongoDB配置文件**
```yaml
# mongod.conf
systemLog:
destination: file
logAppend: true
path: /var/log/mongodb/mongod.log
storage:
dbPath: /var/lib/mongodb
journal:
enabled: true
processManagement:
fork: true
pidFilePath: /var/run/mongodb/mongod.pid
net:
port: 27017
bindIpAll: true
security:
authorization: enabled
replication:
replSetName: 'rs0'
```
---
## 🔧 环境变量配置
### 完整环境变量列表
```env
# .env.production
# ======================
# 应用基础配置
# ======================
NODE_ENV=production
PORT=3001
APP_NAME=Telegram管理系统
APP_VERSION=2.0.0
# ======================
# 数据库配置
# ======================
# MySQL配置
DB_HOST=mysql
DB_PORT=3306
DB_NAME=telegram_system
DB_USER=app_user
DB_PASSWORD=your_secure_mysql_password
DB_POOL_MIN=5
DB_POOL_MAX=50
DB_TIMEOUT=60000
# Redis配置
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=your_secure_redis_password
REDIS_DB=0
REDIS_KEY_PREFIX=telegram:
REDIS_CONNECT_TIMEOUT=10000
# MongoDB配置
MONGODB_URI=mongodb://app_user:your_mongodb_password@mongodb:27017/telegram_system_logs
MONGODB_OPTIONS={"authSource":"telegram_system_logs","useNewUrlParser":true}
# ======================
# 安全配置
# ======================
# JWT配置
JWT_SECRET=your_very_secure_jwt_secret_key_at_least_32_characters
JWT_EXPIRE=7d
REFRESH_TOKEN_SECRET=your_refresh_token_secret_key
REFRESH_TOKEN_EXPIRE=30d
# 加密配置
ENCRYPTION_KEY=your_32_character_encryption_key
HASH_ROUNDS=12
# CORS配置
CORS_ORIGINS=https://yourdomain.com,https://api.yourdomain.com
CORS_CREDENTIALS=true
# 安全头配置
HELMET_ENABLED=true
CSP_ENABLED=true
# ======================
# 第三方服务配置
# ======================
# Telegram配置
TELEGRAM_BOT_TOKEN=your_telegram_bot_token
TELEGRAM_WEBHOOK_URL=https://api.yourdomain.com/webhook/telegram
TELEGRAM_API_URL=https://api.telegram.org/bot
TELEGRAM_RATE_LIMIT=30
# 邮件配置
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_SECURE=false
SMTP_USER=your_email@gmail.com
SMTP_PASS=your_app_password
SMTP_FROM_NAME=Telegram管理系统
SMTP_FROM_EMAIL=noreply@yourdomain.com
# 短信配置
SMS_PROVIDER=aliyun
SMS_ACCESS_KEY=your_sms_access_key
SMS_SECRET_KEY=your_sms_secret_key
SMS_SIGN_NAME=你的签名
SMS_TEMPLATE_CODE=SMS_123456789
# ======================
# 文件存储配置
# ======================
# 本地存储
FILE_STORAGE_TYPE=local
FILE_STORAGE_PATH=/app/uploads
FILE_STORAGE_URL=https://yourdomain.com/uploads
# 云存储阿里云OSS
# FILE_STORAGE_TYPE=oss
# OSS_REGION=oss-cn-beijing
# OSS_ACCESS_KEY_ID=your_oss_access_key
# OSS_ACCESS_KEY_SECRET=your_oss_secret_key
# OSS_BUCKET=your_bucket_name
# OSS_ENDPOINT=https://oss-cn-beijing.aliyuncs.com
# 文件限制
MAX_FILE_SIZE=10485760
ALLOWED_FILE_TYPES=jpg,jpeg,png,gif,pdf,doc,docx,xls,xlsx
# ======================
# 性能配置
# ======================
# 缓存配置
CACHE_TTL=3600
CACHE_MAX_SIZE=100
ENABLE_CACHE=true
# 限流配置
RATE_LIMIT_ENABLED=true
RATE_LIMIT_MAX=100
RATE_LIMIT_WINDOW=60000
RATE_LIMIT_SKIP_SUCCESSFUL=false
# 会话配置
SESSION_SECRET=your_session_secret_key
SESSION_TTL=86400
SESSION_STORE=redis
# ======================
# 日志配置
# ======================
LOG_LEVEL=info
LOG_FORMAT=json
LOG_FILE_ENABLED=true
LOG_FILE_PATH=/app/logs/app.log
LOG_FILE_MAX_SIZE=100m
LOG_FILE_MAX_FILES=10
# 访问日志
ACCESS_LOG_ENABLED=true
ACCESS_LOG_PATH=/app/logs/access.log
# 错误日志
ERROR_LOG_ENABLED=true
ERROR_LOG_PATH=/app/logs/error.log
# ======================
# 监控配置
# ======================
# 健康检查
HEALTH_CHECK_ENABLED=true
HEALTH_CHECK_TIMEOUT=5000
# 性能监控
PERFORMANCE_MONITORING=true
METRICS_ENDPOINT=/metrics
# APM配置
APM_ENABLED=false
APM_SERVICE_NAME=telegram-system-api
APM_SERVER_URL=http://apm-server:8200
# ======================
# WebSocket配置
# ======================
WS_ENABLED=true
WS_PORT=3001
WS_PATH=/ws
WS_HEARTBEAT_INTERVAL=30000
WS_TIMEOUT=60000
# ======================
# 队列配置
# ======================
QUEUE_ENABLED=true
QUEUE_REDIS_HOST=redis
QUEUE_REDIS_PORT=6379
QUEUE_REDIS_DB=1
QUEUE_CONCURRENCY=5
# 消息队列
MESSAGE_QUEUE_NAME=message_tasks
MESSAGE_QUEUE_ATTEMPTS=3
MESSAGE_QUEUE_DELAY=5000
# ======================
# 开发配置(仅开发环境)
# ======================
# DEBUG模式
DEBUG=false
DEVELOPMENT_FEATURES=false
# 热重载
HOT_RELOAD=false
# 测试配置
ENABLE_TEST_ROUTES=false
TEST_DATA_ENABLED=false
```
### 环境变量验证
创建环境变量验证脚本:
```javascript
// scripts/validate-env.js
const requiredVars = [
'NODE_ENV',
'PORT',
'DB_HOST',
'DB_NAME',
'DB_USER',
'DB_PASSWORD',
'REDIS_HOST',
'JWT_SECRET',
'TELEGRAM_BOT_TOKEN',
];
const optionalVars = [
'MONGODB_URI',
'SMTP_HOST',
'SMS_PROVIDER',
'FILE_STORAGE_TYPE',
];
function validateEnvironment() {
const missing = [];
const warnings = [];
// 检查必需变量
requiredVars.forEach((varName) => {
if (!process.env[varName]) {
missing.push(varName);
}
});
// 检查可选变量
optionalVars.forEach((varName) => {
if (!process.env[varName]) {
warnings.push(varName);
}
});
// 检查JWT密钥长度
if (process.env.JWT_SECRET && process.env.JWT_SECRET.length < 32) {
missing.push('JWT_SECRET (must be at least 32 characters)');
}
// 输出结果
if (missing.length > 0) {
console.error('❌ Missing required environment variables:');
missing.forEach((varName) => {
console.error(` - ${varName}`);
});
process.exit(1);
}
if (warnings.length > 0) {
console.warn('⚠️ Optional environment variables not set:');
warnings.forEach((varName) => {
console.warn(` - ${varName}`);
});
}
console.log('✅ Environment validation passed');
}
if (require.main === module) {
validateEnvironment();
}
module.exports = { validateEnvironment };
```
运行验证:
```bash
node scripts/validate-env.js
```
---
## 🔒 SSL证书配置
### 使用Let's Encrypt免费证书
1. **安装Certbot**
```bash
# Ubuntu/Debian
sudo apt update
sudo apt install certbot python3-certbot-nginx
# CentOS/Rocky Linux
sudo dnf install certbot python3-certbot-nginx
```
2. **获取SSL证书**
```bash
# 为域名申请证书
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com -d api.yourdomain.com
# 或者使用DNS验证推荐
sudo certbot certonly --dns-cloudflare \
--dns-cloudflare-credentials ~/.secrets/cloudflare.ini \
-d yourdomain.com \
-d "*.yourdomain.com"
```
3. **自动续期配置**
```bash
# 添加到crontab
sudo crontab -e
# 添加以下行(每天检查一次)
0 2 * * * /usr/bin/certbot renew --quiet --post-hook "systemctl reload nginx"
```
### Nginx SSL配置
```nginx
# /etc/nginx/sites-available/telegram-system
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name yourdomain.com www.yourdomain.com;
# SSL配置
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
# SSL安全配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# HSTS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# 其他安全头
add_header X-Frame-Options DENY always;
add_header X-Content-Type-Options nosniff always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# 前端静态文件
root /var/www/telegram-system/dist;
index index.html;
# Gzip压缩
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json;
# 静态文件缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# API代理
location /api/ {
proxy_pass http://backend-service: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_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# 缓冲配置
proxy_buffering on;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
}
# WebSocket代理
location /ws {
proxy_pass http://backend-service: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;
# WebSocket特定配置
proxy_read_timeout 86400;
proxy_send_timeout 86400;
}
# SPA路由支持
location / {
try_files $uri $uri/ /index.html;
}
# 健康检查
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}
# API子域名
server {
listen 443 ssl http2;
server_name api.yourdomain.com;
# SSL配置复用主域名证书
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
# 直接代理到后端
location / {
proxy_pass http://backend-service: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;
}
}
```
### 安全最佳实践
1. **SSL配置测试**
```bash
# 使用SSL Labs测试
curl -s "https://api.ssllabs.com/api/v3/analyze?host=yourdomain.com" | jq .
# 使用testssl.sh
git clone https://github.com/drwetter/testssl.sh.git
cd testssl.sh
./testssl.sh yourdomain.com
```
2. **HTTP安全头检查**
```bash
# 检查安全头
curl -I https://yourdomain.com
# 使用securityheaders.com
curl -s "https://securityheaders.com/?q=yourdomain.com&hide=on&followRedirects=on" | grep grade
```
---
## 📊 监控与日志
### 系统监控
1. **Prometheus + Grafana部署**
```yaml
# docker-compose.monitoring.yml
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
ports:
- '9090:9090'
volumes:
- ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/usr/share/prometheus/console_libraries'
- '--web.console.templates=/usr/share/prometheus/consoles'
- '--web.enable-lifecycle'
grafana:
image: grafana/grafana:latest
container_name: grafana
ports:
- '3000:3000'
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin123
volumes:
- grafana_data:/var/lib/grafana
- ./monitoring/grafana/dashboards:/etc/grafana/provisioning/dashboards
- ./monitoring/grafana/datasources:/etc/grafana/provisioning/datasources
node-exporter:
image: prom/node-exporter:latest
container_name: node-exporter
ports:
- '9100:9100'
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
- /run/systemd/private:/run/systemd/private:ro
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
- '--collector.filesystem.ignored-mount-points=^/(sys|proc|dev|host|etc)($$|/)'
alertmanager:
image: prom/alertmanager:latest
container_name: alertmanager
ports:
- '9093:9093'
volumes:
- ./monitoring/alertmanager.yml:/etc/alertmanager/alertmanager.yml
volumes:
prometheus_data:
grafana_data:
```
2. **Prometheus配置**
```yaml
# monitoring/prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
rule_files:
- 'rules/*.yml'
alerting:
alertmanagers:
- static_configs:
- targets:
- alertmanager:9093
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'node-exporter'
static_configs:
- targets: ['node-exporter:9100']
- job_name: 'telegram-backend'
static_configs:
- targets: ['backend:3001']
metrics_path: '/metrics'
scrape_interval: 30s
- job_name: 'mysql'
static_configs:
- targets: ['mysql-exporter:9104']
- job_name: 'redis'
static_configs:
- targets: ['redis-exporter:9121']
```
3. **告警规则**
```yaml
# monitoring/rules/alerts.yml
groups:
- name: telegram-system-alerts
rules:
- alert: HighCPUUsage
expr: 100 - (avg by(instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
for: 5m
labels:
severity: warning
annotations:
summary: 'High CPU usage detected'
description: 'CPU usage is above 80% for more than 5 minutes'
- alert: HighMemoryUsage
expr: (node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100 > 90
for: 5m
labels:
severity: critical
annotations:
summary: 'High memory usage detected'
description: 'Memory usage is above 90% for more than 5 minutes'
- alert: ApplicationDown
expr: up{job="telegram-backend"} == 0
for: 1m
labels:
severity: critical
annotations:
summary: 'Application is down'
description: 'Telegram system backend is not responding'
- alert: DatabaseConnectionFailure
expr: mysql_up == 0
for: 2m
labels:
severity: critical
annotations:
summary: 'Database connection failure'
description: 'Cannot connect to MySQL database'
- alert: HighErrorRate
expr: rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m]) * 100 > 5
for: 2m
labels:
severity: warning
annotations:
summary: 'High error rate detected'
description: 'Error rate is above 5% for more than 2 minutes'
```
### 日志管理
1. **ELK Stack部署**
```yaml
# docker-compose.elk.yml
version: '3.8'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.17.0
container_name: elasticsearch
environment:
- discovery.type=single-node
- 'ES_JAVA_OPTS=-Xms1g -Xmx1g'
ports:
- '9200:9200'
volumes:
- elasticsearch_data:/usr/share/elasticsearch/data
logstash:
image: docker.elastic.co/logstash/logstash:7.17.0
container_name: logstash
volumes:
- ./elk/logstash/config:/usr/share/logstash/pipeline
- ./elk/logstash/logstash.yml:/usr/share/logstash/config/logstash.yml
ports:
- '5044:5044'
depends_on:
- elasticsearch
kibana:
image: docker.elastic.co/kibana/kibana:7.17.0
container_name: kibana
ports:
- '5601:5601'
environment:
ELASTICSEARCH_HOSTS: http://elasticsearch:9200
depends_on:
- elasticsearch
volumes:
elasticsearch_data:
```
2. **Logstash配置**
```ruby
# elk/logstash/config/pipeline.conf
input {
beats {
port => 5044
}
tcp {
port => 5000
codec => json_lines
}
}
filter {
if [fields][service] == "telegram-system" {
json {
source => "message"
}
date {
match => [ "timestamp", "ISO8601" ]
}
if [level] == "error" {
mutate {
add_tag => [ "error" ]
}
}
# 解析用户代理
if [userAgent] {
useragent {
source => "userAgent"
target => "ua"
}
}
# IP地理位置
if [clientIP] {
geoip {
source => "clientIP"
target => "geoip"
}
}
}
}
output {
elasticsearch {
hosts => ["elasticsearch:9200"]
index => "telegram-system-%{+YYYY.MM.dd}"
}
if "error" in [tags] {
email {
to => "admin@yourdomain.com"
subject => "Telegram System Error Alert"
body => "Error: %{message}\nTimestamp: %{timestamp}\nLevel: %{level}"
}
}
}
```
3. **应用日志配置**
```javascript
// backend/utils/logger.js
const winston = require('winston');
require('winston-daily-rotate-file');
const logFormat = winston.format.combine(
winston.format.timestamp(),
winston.format.errors({ stack: true }),
winston.format.json(),
);
const logger = winston.createLogger({
level: process.env.LOG_LEVEL || 'info',
format: logFormat,
defaultMeta: {
service: 'telegram-system',
version: process.env.APP_VERSION,
},
transports: [
// 控制台输出
new winston.transports.Console({
format: winston.format.combine(
winston.format.colorize(),
winston.format.simple(),
),
}),
// 文件输出
new winston.transports.DailyRotateFile({
filename: 'logs/app-%DATE%.log',
datePattern: 'YYYY-MM-DD',
maxSize: '20m',
maxFiles: '14d',
level: 'info',
}),
// 错误日志
new winston.transports.DailyRotateFile({
filename: 'logs/error-%DATE%.log',
datePattern: 'YYYY-MM-DD',
maxSize: '20m',
maxFiles: '30d',
level: 'error',
}),
// 发送到Logstash
new winston.transports.Http({
host: 'logstash',
port: 5000,
level: 'warn',
}),
],
});
module.exports = logger;
```
---
## 💾 备份与恢复
### 数据库备份
1. **MySQL备份脚本**
```bash
#!/bin/bash
# scripts/backup-mysql.sh
# 配置
BACKUP_DIR="/opt/backups/mysql"
DB_NAME="telegram_system"
DB_USER="backup_user"
DB_PASSWORD="backup_password"
DB_HOST="localhost"
RETENTION_DAYS=30
# 创建备份目录
mkdir -p $BACKUP_DIR
# 生成备份文件名
BACKUP_FILE="$BACKUP_DIR/telegram_system_$(date +%Y%m%d_%H%M%S).sql"
# 执行备份
mysqldump -h $DB_HOST -u $DB_USER -p$DB_PASSWORD \
--single-transaction \
--routines \
--triggers \
--events \
--hex-blob \
--complete-insert \
$DB_NAME > $BACKUP_FILE
# 压缩备份文件
gzip $BACKUP_FILE
# 删除旧备份
find $BACKUP_DIR -name "*.sql.gz" -mtime +$RETENTION_DAYS -delete
# 验证备份
if [ -f "$BACKUP_FILE.gz" ]; then
echo "Backup completed successfully: $BACKUP_FILE.gz"
# 上传到云存储(可选)
# aws s3 cp "$BACKUP_FILE.gz" s3://your-backup-bucket/mysql/
else
echo "Backup failed!"
exit 1
fi
```
2. **Redis备份脚本**
```bash
#!/bin/bash
# scripts/backup-redis.sh
BACKUP_DIR="/opt/backups/redis"
REDIS_HOST="localhost"
REDIS_PORT="6379"
REDIS_PASSWORD="your_redis_password"
RETENTION_DAYS=7
mkdir -p $BACKUP_DIR
# 触发Redis保存
redis-cli -h $REDIS_HOST -p $REDIS_PORT -a $REDIS_PASSWORD BGSAVE
# 等待保存完成
while [ $(redis-cli -h $REDIS_HOST -p $REDIS_PORT -a $REDIS_PASSWORD LASTSAVE) -eq $(redis-cli -h $REDIS_HOST -p $REDIS_PORT -a $REDIS_PASSWORD LASTSAVE) ]; do
sleep 1
done
# 复制RDB文件
BACKUP_FILE="$BACKUP_DIR/redis_$(date +%Y%m%d_%H%M%S).rdb"
cp /var/lib/redis/dump.rdb $BACKUP_FILE
# 压缩
gzip $BACKUP_FILE
# 清理旧备份
find $BACKUP_DIR -name "*.rdb.gz" -mtime +$RETENTION_DAYS -delete
echo "Redis backup completed: $BACKUP_FILE.gz"
```
3. **MongoDB备份脚本**
```bash
#!/bin/bash
# scripts/backup-mongodb.sh
BACKUP_DIR="/opt/backups/mongodb"
DB_NAME="telegram_system_logs"
MONGO_HOST="localhost"
MONGO_PORT="27017"
MONGO_USER="backup_user"
MONGO_PASSWORD="backup_password"
RETENTION_DAYS=14
mkdir -p $BACKUP_DIR
BACKUP_FILE="$BACKUP_DIR/mongodb_$(date +%Y%m%d_%H%M%S)"
# 执行备份
mongodump \
--host $MONGO_HOST:$MONGO_PORT \
--username $MONGO_USER \
--password $MONGO_PASSWORD \
--db $DB_NAME \
--out $BACKUP_FILE
# 压缩备份
tar -czf "$BACKUP_FILE.tar.gz" -C $BACKUP_DIR $(basename $BACKUP_FILE)
rm -rf $BACKUP_FILE
# 清理旧备份
find $BACKUP_DIR -name "*.tar.gz" -mtime +$RETENTION_DAYS -delete
echo "MongoDB backup completed: $BACKUP_FILE.tar.gz"
```
### 自动化备份
1. **Crontab配置**
```bash
# 编辑crontab
sudo crontab -e
# 添加备份任务
# MySQL备份 - 每天凌晨2点
0 2 * * * /opt/telegram-system/scripts/backup-mysql.sh >> /var/log/backup-mysql.log 2>&1
# Redis备份 - 每6小时
0 */6 * * * /opt/telegram-system/scripts/backup-redis.sh >> /var/log/backup-redis.log 2>&1
# MongoDB备份 - 每天凌晨3点
0 3 * * * /opt/telegram-system/scripts/backup-mongodb.sh >> /var/log/backup-mongodb.log 2>&1
# 文件备份 - 每周日凌晨1点
0 1 * * 0 /opt/telegram-system/scripts/backup-files.sh >> /var/log/backup-files.log 2>&1
```
2. **文件备份脚本**
```bash
#!/bin/bash
# scripts/backup-files.sh
BACKUP_DIR="/opt/backups/files"
SOURCE_DIR="/opt/telegram-system/uploads"
RETENTION_DAYS=90
mkdir -p $BACKUP_DIR
BACKUP_FILE="$BACKUP_DIR/files_$(date +%Y%m%d_%H%M%S).tar.gz"
# 备份上传文件
tar -czf $BACKUP_FILE -C $(dirname $SOURCE_DIR) $(basename $SOURCE_DIR)
# 清理旧备份
find $BACKUP_DIR -name "*.tar.gz" -mtime +$RETENTION_DAYS -delete
echo "Files backup completed: $BACKUP_FILE"
```
### 恢复流程
1. **MySQL恢复**
```bash
#!/bin/bash
# scripts/restore-mysql.sh
BACKUP_FILE=$1
DB_NAME="telegram_system"
DB_USER="root"
DB_PASSWORD="root_password"
DB_HOST="localhost"
if [ -z "$BACKUP_FILE" ]; then
echo "Usage: $0 <backup_file>"
exit 1
fi
# 解压备份文件
if [[ $BACKUP_FILE == *.gz ]]; then
gunzip -c $BACKUP_FILE > /tmp/restore.sql
RESTORE_FILE="/tmp/restore.sql"
else
RESTORE_FILE=$BACKUP_FILE
fi
# 停止应用服务
docker-compose stop backend
# 删除现有数据库
mysql -h $DB_HOST -u $DB_USER -p$DB_PASSWORD -e "DROP DATABASE IF EXISTS $DB_NAME;"
mysql -h $DB_HOST -u $DB_USER -p$DB_PASSWORD -e "CREATE DATABASE $DB_NAME CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
# 恢复数据
mysql -h $DB_HOST -u $DB_USER -p$DB_PASSWORD $DB_NAME < $RESTORE_FILE
# 清理临时文件
if [ "$RESTORE_FILE" = "/tmp/restore.sql" ]; then
rm /tmp/restore.sql
fi
# 重启应用服务
docker-compose start backend
echo "MySQL restore completed from: $BACKUP_FILE"
```
2. **灾难恢复计划**
```bash
#!/bin/bash
# scripts/disaster-recovery.sh
echo "Starting disaster recovery process..."
# 1. 停止所有服务
echo "Stopping all services..."
docker-compose down
# 2. 恢复数据库
echo "Restoring databases..."
./scripts/restore-mysql.sh /opt/backups/mysql/latest.sql.gz
./scripts/restore-redis.sh /opt/backups/redis/latest.rdb.gz
./scripts/restore-mongodb.sh /opt/backups/mongodb/latest.tar.gz
# 3. 恢复文件
echo "Restoring files..."
tar -xzf /opt/backups/files/latest.tar.gz -C /opt/telegram-system/
# 4. 重新启动服务
echo "Starting services..."
docker-compose up -d
# 5. 验证服务
echo "Verifying services..."
sleep 30
# 检查服务状态
if curl -f http://localhost:3001/health; then
echo "✅ Disaster recovery completed successfully"
else
echo "❌ Disaster recovery failed - manual intervention required"
exit 1
fi
```
---
## 🔧 故障排除
### 常见问题
#### 1. 应用无法启动
**问题症状**
- 容器启动失败
- 应用日志显示连接错误
- 健康检查失败
**解决步骤**
```bash
# 检查容器状态
docker-compose ps
# 查看详细日志
docker-compose logs backend
# 检查环境变量
docker-compose exec backend printenv
# 检查网络连接
docker-compose exec backend ping mysql
docker-compose exec backend ping redis
# 验证数据库连接
docker-compose exec backend npm run db:check
```
**常见原因**
- 数据库未就绪
- 环境变量配置错误
- 网络连接问题
- 端口冲突
#### 2. 数据库连接失败
**问题症状**
- `ECONNREFUSED` 错误
- 数据库超时
- 认证失败
**解决步骤**
```bash
# 检查MySQL状态
docker-compose exec mysql mysql -u root -p -e "SHOW DATABASES;"
# 检查用户权限
docker-compose exec mysql mysql -u root -p -e "SELECT User, Host FROM mysql.user;"
# 测试连接
docker-compose exec backend mysql -h mysql -u app_user -p
# 检查网络
docker network ls
docker network inspect telegram-system_default
```
#### 3. Redis连接问题
**问题症状**
- 缓存功能异常
- 会话丢失
- WebSocket连接问题
**解决步骤**
```bash
# 检查Redis状态
docker-compose exec redis redis-cli ping
# 测试认证
docker-compose exec redis redis-cli -a your_password ping
# 检查配置
docker-compose exec redis redis-cli config get "*"
# 查看连接信息
docker-compose exec redis redis-cli info clients
```
#### 4. 前端无法访问后端
**问题症状**
- API请求失败
- CORS错误
- 502/504错误
**解决步骤**
```bash
# 检查Nginx配置
nginx -t
# 重新加载Nginx
nginx -s reload
# 检查代理配置
curl -I http://localhost/api/health
# 检查网络连接
telnet backend 3001
```
#### 5. SSL证书问题
**问题症状**
- 证书过期警告
- SSL握手失败
- 混合内容错误
**解决步骤**
```bash
# 检查证书状态
openssl x509 -in /etc/letsencrypt/live/yourdomain.com/cert.pem -text -noout
# 验证证书链
openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt /etc/letsencrypt/live/yourdomain.com/cert.pem
# 续期证书
certbot renew --dry-run
# 检查证书有效期
certbot certificates
```
### 性能问题排查
#### 1. 响应时间过长
**排查步骤**
```bash
# 检查系统资源
top
htop
iostat -x 1
# 检查数据库性能
docker-compose exec mysql mysql -u root -p -e "SHOW PROCESSLIST;"
docker-compose exec mysql mysql -u root -p -e "SHOW STATUS LIKE 'Slow_queries';"
# 检查Redis性能
docker-compose exec redis redis-cli --latency
docker-compose exec redis redis-cli info stats
# 分析应用日志
tail -f logs/app.log | grep -E "(slow|timeout|error)"
```
#### 2. 内存使用过高
**排查步骤**
```bash
# 检查容器内存使用
docker stats
# 检查Node.js内存泄漏
docker-compose exec backend node --expose-gc --inspect=0.0.0.0:9229 server.js
# 分析heap dump
npm install -g heapdump
```
#### 3. 数据库锁等待
**排查步骤**
```bash
# 检查锁等待
docker-compose exec mysql mysql -u root -p -e "SHOW ENGINE INNODB STATUS\G" | grep -A 10 "TRANSACTIONS"
# 查看当前事务
docker-compose exec mysql mysql -u root -p -e "SELECT * FROM information_schema.innodb_trx;"
# 查看锁等待
docker-compose exec mysql mysql -u root -p -e "SELECT * FROM information_schema.innodb_locks;"
```
### 日志分析
#### 应用日志分析
```bash
# 错误日志分析
grep -E "ERROR|FATAL" logs/app.log | tail -n 50
# 慢查询分析
grep "slow query" logs/app.log | awk '{print $NF}' | sort | uniq -c | sort -nr
# API错误统计
grep "api_error" logs/access.log | cut -d' ' -f7 | sort | uniq -c | sort -nr
# 用户活动分析
grep "user_action" logs/app.log | cut -d' ' -f4 | sort | uniq -c | sort -nr
```
#### 系统日志分析
```bash
# 系统错误
journalctl -u docker -f
# 内核日志
dmesg | tail -n 50
# 磁盘空间检查
df -h
du -sh /opt/telegram-system/* | sort -h
```
### 监控告警处理
#### 告警响应流程
1. **收到告警**
- 查看告警详情
- 确认告警级别
- 开始故障处理
2. **问题排查**
- 检查监控面板
- 分析相关日志
- 确定问题范围
3. **问题修复**
- 实施修复措施
- 验证修复效果
- 更新告警状态
4. **后续跟进**
- 编写事故报告
- 优化监控规则
- 预防类似问题
### 应急处理脚本
```bash
#!/bin/bash
# scripts/emergency-response.sh
ISSUE_TYPE=$1
case $ISSUE_TYPE in
"high-cpu")
echo "处理高CPU使用率问题..."
# 重启应用服务
docker-compose restart backend
# 清理临时文件
docker system prune -f
;;
"high-memory")
echo "处理高内存使用问题..."
# 清理缓存
docker-compose exec redis redis-cli FLUSHDB
# 重启服务
docker-compose restart backend
;;
"database-down")
echo "处理数据库故障..."
# 尝试重启数据库
docker-compose restart mysql
# 检查数据完整性
docker-compose exec mysql mysqlcheck --all-databases
;;
"disk-full")
echo "处理磁盘空间不足..."
# 清理日志文件
find /var/log -name "*.log" -mtime +7 -delete
# 清理Docker缓存
docker system prune -a -f
# 清理备份文件
find /opt/backups -mtime +30 -delete
;;
*)
echo "用法: $0 {high-cpu|high-memory|database-down|disk-full}"
exit 1
;;
esac
echo "应急处理完成,请检查系统状态"
```
---
## 📚 附录
### 部署检查清单
#### 部署前检查
- [ ] 服务器资源满足要求
- [ ] 域名DNS配置正确
- [ ] SSL证书已申请
- [ ] 环境变量已配置
- [ ] 数据库已创建
- [ ] 备份策略已制定
#### 部署过程检查
- [ ] 代码版本正确
- [ ] 构建过程无错误
- [ ] 数据库迁移成功
- [ ] 服务启动正常
- [ ] 健康检查通过
- [ ] SSL证书生效
#### 部署后验证
- [ ] 前端页面可访问
- [ ] API接口正常
- [ ] 用户登录功能
- [ ] 数据库连接正常
- [ ] 缓存功能正常
- [ ] WebSocket连接正常
- [ ] 邮件发送功能
- [ ] 文件上传功能
- [ ] 监控告警配置
### 常用命令
#### Docker相关
```bash
# 查看服务状态
docker-compose ps
# 查看日志
docker-compose logs -f backend
# 重启服务
docker-compose restart backend
# 进入容器
docker-compose exec backend bash
# 更新服务
docker-compose pull
docker-compose up -d
# 清理资源
docker system prune -f
```
#### 数据库相关
```bash
# 连接MySQL
docker-compose exec mysql mysql -u root -p
# 导出数据库
docker-compose exec mysql mysqldump -u root -p telegram_system > backup.sql
# 导入数据库
docker-compose exec -T mysql mysql -u root -p telegram_system < backup.sql
# 检查Redis
docker-compose exec redis redis-cli ping
# MongoDB操作
docker-compose exec mongodb mongo telegram_system_logs
```
#### 系统维护
```bash
# 检查磁盘空间
df -h
# 检查内存使用
free -h
# 检查系统负载
uptime
# 查看网络连接
netstat -tlnp
# 检查端口占用
lsof -i :3001
```
### 联系方式
- **技术支持**: support@yourdomain.com
- **紧急联系**: +86-138-0000-0000
- **文档地址**: https://docs.yourdomain.com
- **监控地址**: https://monitor.yourdomain.com
---
**最后更新**: 2024-01-20
**文档版本**: v2.0.0
> 本部署指南涵盖了从开发环境到生产环境的完整部署流程。如有疑问或需要支持,请联系技术团队。