# 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: REDIS_PASSWORD: JWT_SECRET: TELEGRAM_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 " 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 > 本部署指南涵盖了从开发环境到生产环境的完整部署流程。如有疑问或需要支持,请联系技术团队。