You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
13 KiB
13 KiB
A股智投分析平台 - 部署文档
一、前端部署
1.1 构建
cd /mnt/okcomputer/output/app
# 安装依赖
npm install
# 开发模式
npm run dev
# 构建生产版本
npm run build
1.2 构建输出
构建完成后,文件位于 dist/ 目录:
dist/
├── index.html # 入口HTML
├── assets/
│ ├── index-xxx.js # JS bundle
│ ├── index-xxx.css # CSS bundle
│ └── ...
└── ...
1.3 部署方式
方式一: 静态服务器
# 使用 serve
npx serve dist
# 使用 Python
python -m http.server 8080 --directory dist
# 使用 Nginx
cp -r dist/* /var/www/html/
方式二: Nginx 配置
server {
listen 80;
server_name aguzhitou.com;
root /var/www/aguzhitou;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location /assets {
expires 1y;
add_header Cache-Control "public, immutable";
}
# Gzip压缩
gzip on;
gzip_types text/plain text/css application/json application/javascript;
}
方式三: CDN 部署
# 阿里云 OSS
ossutil cp -r dist/ oss://aguzhitou-bucket/
# 腾讯云 COS
coscmd upload -r dist/ /
# AWS S3
aws s3 sync dist/ s3://aguzhitou-bucket/
方式四: Docker 部署
# Dockerfile
FROM nginx:alpine
COPY dist/ /usr/share/nginx/html/
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
# 构建镜像
docker build -t aguzhitou-frontend .
# 运行容器
docker run -d -p 80:80 --name aguzhitou-frontend aguzhitou-frontend
二、后端部署
2.1 环境准备
# 安装 Node.js 20
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs
# 安装 MySQL
sudo apt-get install mysql-server
# 安装 Redis
sudo apt-get install redis-server
2.2 数据库初始化
# 创建数据库
mysql -u root -p
CREATE DATABASE aguzhitou CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'aguzhitou'@'localhost' IDENTIFIED BY 'your-password';
GRANT ALL PRIVILEGES ON aguzhitou.* TO 'aguzhitou'@'localhost';
FLUSH PRIVILEGES;
2.3 后端部署
cd backend
# 安装依赖
npm install
# 生成 Prisma Client
npx prisma generate
# 执行数据库迁移
npx prisma migrate deploy
# 构建
npm run build
# 启动
npm start
# 或使用 PM2
pm2 start dist/app.js --name aguzhitou-api
2.4 Docker Compose 部署
# 启动所有服务
docker-compose up -d
# 查看日志
docker-compose logs -f app
# 停止服务
docker-compose down
三、完整部署架构
┌─────────────────────────────────────┐
│ 用户 │
└─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ CDN (静态资源) │
│ 阿里云/腾讯云/AWS │
└─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ Nginx (负载均衡) │
│ 反向代理 + SSL │
└─────────────────────────────────────┘
│
┌───────────────────┼───────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ Frontend 1 │ │ Frontend 2 │ │ Frontend 3 │
│ (Nginx) │ │ (Nginx) │ │ (Nginx) │
└────────┬─────────┘ └────────┬─────────┘ └────────┬─────────┘
│ │ │
└─────────────────────┼─────────────────────┘
│
▼
┌──────────────────────────┐
│ Backend API │
│ (Node.js) │
│ x3 实例 │
└───────────┬──────────────┘
│
┌────────────────┼────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────────┐ ┌──────────────┐ ┌──────────────┐
│ MySQL 主从 │ │ Redis │ │ WebSocket │
│ (主库+从库) │ │ Cluster │ │ Server │
└──────────────────┘ └──────────────┘ └──────────────┘
四、环境配置
4.1 生产环境变量
# /etc/environment
# 应用配置
NODE_ENV=production
PORT=3000
# 数据库
DATABASE_URL=mysql://aguzhitou:password@localhost:3306/aguzhitou
# Redis
REDIS_URL=redis://localhost:6379
# JWT
JWT_SECRET=your-super-secret-key-min-32-characters
JWT_EXPIRES_IN=7d
# 日志
LOG_LEVEL=info
# 外部API
AKSHARE_URL=http://localhost:8000
4.2 Nginx 完整配置
# /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# Gzip
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;
# 前端
server {
listen 80;
server_name aguzhitou.com www.aguzhitou.com;
# 重定向到 HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name aguzhitou.com www.aguzhitou.com;
ssl_certificate /etc/nginx/ssl/aguzhitou.crt;
ssl_certificate_key /etc/nginx/ssl/aguzhitou.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
root /var/www/aguzhitou;
index index.html;
location / {
try_files $uri $uri/ /index.html;
expires -1;
}
location /assets {
expires 1y;
add_header Cache-Control "public, immutable";
}
# API 代理
location /api {
proxy_pass http://localhost:3000;
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;
}
# WebSocket 代理
location /ws {
proxy_pass http://localhost: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;
}
}
}
五、SSL 证书配置
5.1 Let's Encrypt 免费证书
# 安装 Certbot
sudo apt-get install certbot python3-certbot-nginx
# 获取证书
sudo certbot --nginx -d aguzhitou.com -d www.aguzhitou.com
# 自动续期
sudo certbot renew --dry-run
5.2 阿里云 SSL 证书
# 下载证书并放置到
/etc/nginx/ssl/
├── aguzhitou.crt
└── aguzhitou.key
六、监控与日志
6.1 PM2 进程管理
# 安装
npm install -g pm2
# 启动
pm2 start dist/app.js --name aguzhitou-api
# 查看状态
pm2 status
# 查看日志
pm2 logs aguzhitou-api
# 重启
pm2 restart aguzhitou-api
# 保存配置
pm2 save
pm2 startup
6.2 日志收集 (ELK)
# docker-compose.logging.yml
version: '3.8'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.0.0
environment:
- discovery.type=single-node
volumes:
- es_data:/usr/share/elasticsearch/data
logstash:
image: docker.elastic.co/logstash/logstash:8.0.0
volumes:
- ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf
kibana:
image: docker.elastic.co/kibana/kibana:8.0.0
ports:
- "5601:5601"
volumes:
es_data:
6.3 监控告警 (Prometheus + Grafana)
# docker-compose.monitoring.yml
version: '3.8'
services:
prometheus:
image: prom/prometheus
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
ports:
- "9090:9090"
grafana:
image: grafana/grafana
volumes:
- grafana_data:/var/lib/grafana
ports:
- "3000:3000"
volumes:
prometheus_data:
grafana_data:
七、备份策略
7.1 数据库备份
#!/bin/bash
# backup.sh
BACKUP_DIR=/backup/mysql
DATE=$(date +%Y%m%d_%H%M%S)
# 备份
mysqldump -u root -p aguzhitou > $BACKUP_DIR/aguzhitou_$DATE.sql
# 压缩
gzip $BACKUP_DIR/aguzhitou_$DATE.sql
# 保留最近7天
find $BACKUP_DIR -name "*.sql.gz" -mtime +7 -delete
# 上传到云存储
ossutil cp $BACKUP_DIR/aguzhitou_$DATE.sql.gz oss://aguzhitou-backup/
# 添加定时任务
crontab -e
# 每天凌晨2点备份
0 2 * * * /path/to/backup.sh
7.2 Redis 备份
# 开启 RDB 持久化
# redis.conf
save 900 1
save 300 10
save 60 10000
八、故障排查
8.1 常见问题
# 1. 端口被占用
sudo lsof -i :3000
sudo kill -9 <PID>
# 2. 数据库连接失败
mysql -u aguzhitou -p -h localhost
# 3. Redis 连接失败
redis-cli ping
# 4. 查看日志
tail -f /var/log/nginx/error.log
tail -f /var/log/aguzhitou/app.log
# 5. 内存不足
free -h
ps aux --sort=-%mem | head -10
8.2 性能优化
# MySQL 优化
# /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
innodb_buffer_pool_size = 1G
max_connections = 200
query_cache_size = 64M
# Redis 优化
# /etc/redis/redis.conf
maxmemory 512mb
maxmemory-policy allkeys-lru
九、回滚策略
# 1. 备份当前版本
cp -r /var/www/aguzhitou /var/www/aguzhitou-backup-$(date +%Y%m%d)
# 2. 部署新版本
npm run build
cp -r dist/* /var/www/aguzhitou/
# 3. 如果出现问题,回滚
cp -r /var/www/aguzhitou-backup-20240115/* /var/www/aguzhitou/
# 4. 重启服务
pm2 restart aguzhitou-api
sudo systemctl restart nginx
十、部署检查清单
- 服务器环境配置完成
- 数据库创建并初始化
- Redis 服务运行正常
- 后端服务部署成功
- 前端构建并部署
- Nginx 配置正确
- SSL 证书配置
- 域名解析正确
- 日志收集配置
- 监控告警配置
- 备份策略配置
- 性能测试通过
- 安全扫描通过