rwadurian/backend/services/identity-service/docs/DEPLOYMENT_GUIDE.md

1223 lines
41 KiB
Markdown
Raw 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.

# RWA Durian 系统部署指南
本文档描述了 RWA Durian 系统的完整部署架构,包括前端 API 调用、Nginx 反向代理配置和后端服务部署。
## 1. 系统架构概览
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ 用户设备 │
│ (Android/iOS App) │
└─────────────────────────────────┬───────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│ Nginx + MPC-System 服务器 192.168.1.100 (公网) │
│ https://rwaapi.szaiai.com │
│ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ Nginx 反向代理 │ │
│ │ /etc/nginx/conf.d/rwaapi.conf │ │
│ │ │ │
│ │ /api/v1/user/* → 192.168.1.111:3000 (Identity) │ │
│ │ /api/v1/auth/* → 192.168.1.111:3000 (Identity) │ │
│ │ /api/v1/wallet/* → 192.168.1.111:3002 (Wallet) │ │
│ │ /api/v1/trading/* → 192.168.1.111:3002 (Wallet) │ │
│ │ /api/v1/planting/* → 192.168.1.111:3003 (Planting) │ │
│ │ /api/v1/referral/* → 192.168.1.111:3004 (Referral) │ │
│ │ /api/v1/mining/* → 192.168.1.111:3005 (Reward) │ │
│ │ /api/v1/ranking/* → 192.168.1.111:3007 (Leaderboard) │ │
│ │ /api/v1/telemetry/*→ 192.168.1.111:3008 (Reporting) │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌───────────────────────────────────────────────────────────────────────┐ │
│ │ MPC-System (Go 服务) │ │
│ │ localhost:4000 │ │
│ │ • TSS 密钥生成 (Keygen) │ │
│ │ • TSS 签名 (Sign) │ │
│ │ • 密钥分片管理 │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────┬───────────────────────────────────────────┘
│ 内网
┌─────────────────────────────────────────────────────────────────────────────┐
│ 后端服务器 192.168.1.111 │
│ │
│ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │
│ │ Identity │ │ MPC-Service │ │ Wallet │ │ Planting │ │
│ │ :3000 │ │ :3001 │ │ :3002 │ │ :3003 │ │
│ └───────────────┘ └───────────────┘ └───────────────┘ └───────────────┘ │
│ │ │ │
│ │ │ 调用 MPC-System │
│ │ └──────────────────────► 192.168.1.100:4000 │
│ │ │
│ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │
│ │ Referral │ │ Reward │ │ Authorization │ │ Leaderboard │ │
│ │ :3004 │ │ :3005 │ │ :3006 │ │ :3007 │ │
│ └───────────────┘ └───────────────┘ └───────────────┘ └───────────────┘ │
│ │
│ ┌───────────────┐ ┌───────────────┐ │
│ │ Reporting │ │ Backup │ │
│ │ :3008 │ │ :3009 │ │
│ └───────────────┘ └───────────────┘ │
│ │
│ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │
│ │ PostgreSQL │ │ Redis │ │ Kafka │ │
│ │ :5432 │ │ :6379 │ │ :9092 │ │
│ └───────────────┘ └───────────────┘ └───────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
```
### 服务器角色说明
| 服务器 | IP 地址 | 角色 | 部署服务 |
|-------|---------|------|---------|
| Nginx + MPC 服务器 | 192.168.1.100 (公网) | API 网关 + MPC 核心 | Nginx, MPC-System (Go) |
| 后端服务器 | 192.168.1.111 (内网) | 业务微服务 | 所有 NestJS 微服务 + 基础设施 |
### 为什么 MPC-System 部署在 Nginx 服务器上?
**安全隔离原则**: MPC-System 是处理密钥分片的核心安全组件,与业务数据库隔离部署可以:
1. 减少攻击面 - 即使业务服务器被入侵MPC 密钥分片仍然安全
2. 物理隔离 - 密钥分片和业务数据在不同机器上
3. 独立运维 - MPC 系统可以独立升级和维护
## 2. 服务端口规划
### 2.1 Nginx + MPC 服务器 (192.168.1.100)
| 服务名称 | 端口 | 说明 |
|---------|------|------|
| Nginx | 80, 443 | HTTP/HTTPS 反向代理 |
| MPC-System (Go) | 4000 | TSS 密钥生成、签名服务 |
### 2.2 后端服务器 (192.168.1.111)
| 服务名称 | 端口 | API 前缀 | 说明 |
|---------|------|----------|------|
| Identity Service | 3000 | `/api/v1` | 用户身份、认证、钱包创建 |
| MPC Service (NestJS) | 3001 | `/api/v1` | MPC 中间层,调用 MPC-System |
| Wallet Service | 3002 | `/api/v1` | 钱包余额、交易、充值 |
| Planting Service | 3003 | `/api/v1` | 认种业务 |
| Referral Service | 3004 | `/api/v1` | 推荐关系、分享链接 |
| Reward Service | 3005 | `/api/v1` | 挖矿奖励、收益 |
| Authorization Service | 3006 | `/api/v1` | 权限管理 (内部) |
| Leaderboard Service | 3007 | `/api` | 排行榜 |
| Reporting Service | 3008 | `/api/v1` | 遥测统计、报表 |
| Backup Service | 3009 | - | MPC 备份 (内部服务) |
### 2.3 MPC 调用链路
```
用户请求 → Identity Service (3000) → MPC Service (3001) → MPC-System (192.168.1.100:4000)
TSS 密钥生成/签名
```
## 3. Nginx 配置文件
### 3.1 目录结构
在 Nginx 服务器上使用 `sites-available` / `sites-enabled` 标准结构:
```
/etc/nginx/
├── nginx.conf # 主配置文件
├── sites-available/ # 可用站点配置
│ └── rwaapi.szaiai.com.conf # API 网关配置
├── sites-enabled/ # 已启用站点 (软链接)
│ └── rwaapi.szaiai.com.conf → ../sites-available/rwaapi.szaiai.com.conf
└── snippets/ # 可复用配置片段
├── proxy-params.conf # 代理参数
├── cors-params.conf # CORS 跨域配置
└── ssl-params.conf # SSL 安全参数
/etc/letsencrypt/live/rwaapi.szaiai.com/ # Let's Encrypt SSL 证书 (自动管理)
├── fullchain.pem # 完整证书链
├── privkey.pem # 私钥
├── cert.pem # 服务器证书
└── chain.pem # 中间证书
```
**使用 `sites-available/sites-enabled` 的优势:**
- 快速启用/禁用站点:`ln -s` / `rm` 软链接
- 保留配置历史,方便回滚
- 多站点管理更清晰
### 3.2 主配置文件 `/etc/nginx/nginx.conf`
```nginx
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
use epoll;
multi_accept on;
}
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" '
'rt=$request_time uct="$upstream_connect_time" '
'uht="$upstream_header_time" urt="$upstream_response_time"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
client_max_body_size 10m;
# 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/xml application/xml+rss text/javascript;
# 限流配置
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
# 加载已启用的站点配置
include /etc/nginx/sites-enabled/*.conf;
}
```
### 3.3 代理参数配置 `/etc/nginx/snippets/proxy-params.conf`
```nginx
proxy_http_version 1.1;
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_set_header Connection "";
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
proxy_busy_buffers_size 8k;
```
### 3.4 CORS 配置 `/etc/nginx/snippets/cors-params.conf`
```nginx
# CORS 预检请求处理
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
# CORS 响应头
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
```
### 3.5 SSL 安全参数 `/etc/nginx/snippets/ssl-params.conf`
```nginx
# SSL 会话配置
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
# 现代 SSL 协议配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# HSTS
add_header Strict-Transport-Security "max-age=63072000" always;
```
### 3.6 API 网关配置 `/etc/nginx/sites-available/rwaapi.szaiai.com.conf`
```nginx
# ============================================
# 后端服务器地址 (192.168.1.111)
# ============================================
upstream identity_service {
server 192.168.1.111:3000;
keepalive 32;
}
upstream wallet_service {
server 192.168.1.111:3002;
keepalive 32;
}
upstream planting_service {
server 192.168.1.111:3003;
keepalive 32;
}
upstream referral_service {
server 192.168.1.111:3004;
keepalive 32;
}
upstream reward_service {
server 192.168.1.111:3005;
keepalive 32;
}
upstream leaderboard_service {
server 192.168.1.111:3007;
keepalive 32;
}
upstream reporting_service {
server 192.168.1.111:3008;
keepalive 32;
}
# ============================================
# HTTP -> HTTPS 重定向
# ============================================
server {
listen 80;
server_name rwaapi.szaiai.com;
return 301 https://$server_name$request_uri;
}
# ============================================
# HTTPS 服务器
# ============================================
server {
listen 443 ssl http2;
server_name rwaapi.szaiai.com;
# Let's Encrypt SSL 证书 (默认路径)
ssl_certificate /etc/letsencrypt/live/rwaapi.szaiai.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/rwaapi.szaiai.com/privkey.pem;
# 引入 SSL 安全参数
include snippets/ssl-params.conf;
# 安全头
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# 限流
limit_req zone=api_limit burst=20 nodelay;
limit_conn conn_limit 10;
# ============================================
# 健康检查端点
# ============================================
location /health {
access_log off;
return 200 '{"status":"ok","timestamp":"$time_iso8601"}';
add_header Content-Type application/json;
}
# ============================================
# Identity Service - 用户身份认证
# POST /api/v1/user/auto-create - 自动创建用户
# POST /api/v1/user/login - 用户登录
# GET /api/v1/user/profile - 获取用户信息
# ============================================
location /api/v1/user {
include snippets/cors-params.conf;
proxy_pass http://identity_service/api/v1/user;
include snippets/proxy-params.conf;
}
location /api/v1/auth {
include snippets/cors-params.conf;
proxy_pass http://identity_service/api/v1/auth;
include snippets/proxy-params.conf;
}
# ============================================
# Wallet Service - 钱包操作
# GET /api/v1/wallet/balance - 查询余额
# POST /api/v1/wallet/create - 创建钱包
# ============================================
location /api/v1/wallet {
include snippets/cors-params.conf;
proxy_pass http://wallet_service/api/v1/wallet;
include snippets/proxy-params.conf;
}
# Trading - 交易
location /api/v1/trading {
include snippets/cors-params.conf;
proxy_pass http://wallet_service/api/v1/trading;
include snippets/proxy-params.conf;
}
# Deposit - 充值
location /api/v1/deposit {
include snippets/cors-params.conf;
proxy_pass http://wallet_service/api/v1/deposit;
include snippets/proxy-params.conf;
}
# ============================================
# Planting Service - 认种业务
# GET /api/v1/planting/price - 认种价格
# POST /api/v1/planting/submit - 提交认种
# ============================================
location /api/v1/planting {
include snippets/cors-params.conf;
proxy_pass http://planting_service/api/v1/planting;
include snippets/proxy-params.conf;
}
# ============================================
# Referral Service - 推荐系统
# GET /api/v1/referral/generate-link - 生成推荐链接
# GET /api/v1/community/referrals - 获取推荐列表
# ============================================
location /api/v1/referral {
include snippets/cors-params.conf;
proxy_pass http://referral_service/api/v1/referral;
include snippets/proxy-params.conf;
}
location /api/v1/community {
include snippets/cors-params.conf;
proxy_pass http://referral_service/api/v1/community;
include snippets/proxy-params.conf;
}
# ============================================
# Reward Service - 挖矿奖励
# GET /api/v1/mining/status - 挖矿状态
# POST /api/v1/mining/start - 开始挖矿
# POST /api/v1/mining/claim - 领取奖励
# ============================================
location /api/v1/mining {
include snippets/cors-params.conf;
proxy_pass http://reward_service/api/v1/mining;
include snippets/proxy-params.conf;
}
location /api/v1/reward {
include snippets/cors-params.conf;
proxy_pass http://reward_service/api/v1/reward;
include snippets/proxy-params.conf;
}
# ============================================
# Leaderboard Service - 排行榜
# GET /api/v1/ranking/daily - 日榜
# GET /api/v1/ranking/weekly - 周榜
# ============================================
location /api/v1/ranking {
include snippets/cors-params.conf;
proxy_pass http://leaderboard_service/api/ranking;
include snippets/proxy-params.conf;
}
location /api/v1/leaderboard {
include snippets/cors-params.conf;
proxy_pass http://leaderboard_service/api/leaderboard;
include snippets/proxy-params.conf;
}
# ============================================
# Reporting Service - 遥测统计
# POST /api/v1/telemetry/session - 上报会话
# POST /api/v1/telemetry/heartbeat - 心跳
# POST /api/v1/telemetry/events - 事件上报
# ============================================
location /api/v1/telemetry {
include snippets/cors-params.conf;
proxy_pass http://reporting_service/api/v1/telemetry;
include snippets/proxy-params.conf;
}
location /api/v1/report {
include snippets/cors-params.conf;
proxy_pass http://reporting_service/api/v1/report;
include snippets/proxy-params.conf;
}
# ============================================
# 默认 404
# ============================================
location / {
return 404 '{"error":"Not Found","message":"API endpoint not found"}';
add_header Content-Type application/json;
}
}
```
## 4. MPC-System 部署 (192.168.1.100)
MPC-System 是一个独立的 Go 服务,负责 TSS (Threshold Signature Scheme) 密钥生成和签名操作。
### 4.1 系统要求
- Go 1.21+
- 最小 2GB RAM
- 10GB 磁盘空间
### 4.2 部署方式
#### 方式一: 直接运行 (推荐生产环境)
```bash
# 1. 创建部署目录
mkdir -p /opt/mpc-system
cd /opt/mpc-system
# 2. 下载或复制编译好的二进制文件
# 从构建服务器复制 mpc-system 可执行文件
scp build-server:/path/to/mpc-system .
# 3. 创建配置文件
cat > config.yaml << 'EOF'
server:
host: 0.0.0.0
port: 4000
# TSS 配置
tss:
threshold: 2 # 签名阈值 (t of n)
parties: 3 # 总参与方数量
# 日志配置
log:
level: info
format: json
output: /var/log/mpc-system/mpc.log
# 安全配置
security:
# 只允许后端服务器访问
allowed_ips:
- 192.168.1.111
# API 认证密钥
api_key: ${MPC_API_KEY}
EOF
# 4. 创建日志目录
mkdir -p /var/log/mpc-system
# 5. 创建 systemd 服务
cat > /etc/systemd/system/mpc-system.service << 'EOF'
[Unit]
Description=MPC System - TSS Key Generation and Signing Service
After=network.target
[Service]
Type=simple
User=mpc
Group=mpc
WorkingDirectory=/opt/mpc-system
ExecStart=/opt/mpc-system/mpc-system -config /opt/mpc-system/config.yaml
Restart=always
RestartSec=5
Environment=MPC_API_KEY=your_secure_api_key_here
# 安全限制
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/log/mpc-system /opt/mpc-system/data
[Install]
WantedBy=multi-user.target
EOF
# 6. 创建专用用户
useradd -r -s /bin/false mpc
chown -R mpc:mpc /opt/mpc-system /var/log/mpc-system
# 7. 启动服务
systemctl daemon-reload
systemctl enable mpc-system
systemctl start mpc-system
# 8. 检查状态
systemctl status mpc-system
curl http://localhost:4000/health
```
#### 方式二: Docker 部署
```bash
# 1. 创建 Dockerfile (如果需要)
cat > /opt/mpc-system/Dockerfile << 'EOF'
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o mpc-system ./cmd/main.go
FROM alpine:3.19
RUN apk add --no-cache ca-certificates
COPY --from=builder /app/mpc-system /usr/local/bin/
COPY --from=builder /app/config.yaml /etc/mpc-system/
EXPOSE 4000
CMD ["mpc-system", "-config", "/etc/mpc-system/config.yaml"]
EOF
# 2. 使用 docker-compose
cat > /opt/mpc-system/docker-compose.yml << 'EOF'
services:
mpc-system:
build: .
ports:
- "4000:4000"
environment:
- MPC_API_KEY=${MPC_API_KEY}
volumes:
- ./config.yaml:/etc/mpc-system/config.yaml:ro
- mpc_data:/opt/mpc-system/data
- mpc_logs:/var/log/mpc-system
restart: unless-stopped
# 网络隔离 - 只允许内网访问
networks:
- internal
networks:
internal:
driver: bridge
internal: true
volumes:
mpc_data:
mpc_logs:
EOF
# 3. 启动
cd /opt/mpc-system
docker compose up -d
```
### 4.3 MPC-System API 端点
| 端点 | 方法 | 说明 |
|------|------|------|
| `/health` | GET | 健康检查 |
| `/api/v1/keygen` | POST | TSS 密钥生成 |
| `/api/v1/sign` | POST | TSS 签名 |
| `/api/v1/reshare` | POST | 密钥重新分片 |
### 4.4 防火墙配置
```bash
# 只允许后端服务器 (192.168.1.111) 访问 MPC-System
iptables -A INPUT -p tcp --dport 4000 -s 192.168.1.111 -j ACCEPT
iptables -A INPUT -p tcp --dport 4000 -j DROP
# 保存规则
iptables-save > /etc/iptables/rules.v4
```
### 4.5 环境变量
在 192.168.1.100 服务器上创建 `/opt/mpc-system/.env`:
```bash
# MPC API 认证密钥 (与 mpc-service 配置一致)
MPC_API_KEY=your_very_secure_api_key_at_least_32_characters
# 日志级别
LOG_LEVEL=info
```
## 5. 后端服务器配置 (192.168.1.111)
### 5.1 Docker Compose 部署文件
在 192.168.1.111 服务器上创建 `/opt/rwadurian/docker-compose.yml`:
```yaml
services:
# ============================================
# 微服务
# ============================================
identity-service:
build: ./services/identity-service
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgresql://postgres:${DB_PASSWORD}@postgres:5432/rwa_identity
- JWT_SECRET=${JWT_SECRET}
- REDIS_HOST=redis
- KAFKA_BROKERS=kafka:29092
- MPC_SERVICE_URL=http://mpc-service:3001
- BACKUP_SERVICE_URL=http://backup-service:3009
- APP_ENV=production
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
networks:
- rwa-network
restart: unless-stopped
mpc-service:
build: ./services/mpc-service
ports:
- "3001:3001"
environment:
- DATABASE_URL=postgresql://postgres:${DB_PASSWORD}@postgres:5432/rwa_mpc
- REDIS_HOST=redis
- APP_ENV=production
# MPC-System 部署在 192.168.1.100 (Nginx 服务器)
- MPC_SYSTEM_URL=http://192.168.1.100:4000
depends_on:
postgres:
condition: service_healthy
networks:
- rwa-network
restart: unless-stopped
wallet-service:
build: ./services/wallet-service
ports:
- "3002:3002"
environment:
- DATABASE_URL=postgresql://postgres:${DB_PASSWORD}@postgres:5432/rwa_wallet
- JWT_SECRET=${JWT_SECRET}
- REDIS_HOST=redis
- KAFKA_BROKERS=kafka:29092
- IDENTITY_SERVICE_URL=http://identity-service:3000
- APP_ENV=production
depends_on:
postgres:
condition: service_healthy
networks:
- rwa-network
restart: unless-stopped
planting-service:
build: ./services/planting-service
ports:
- "3003:3003"
environment:
- DATABASE_URL=postgresql://postgres:${DB_PASSWORD}@postgres:5432/rwa_planting
- JWT_SECRET=${JWT_SECRET}
- REDIS_HOST=redis
- KAFKA_BROKERS=kafka:29092
- WALLET_SERVICE_URL=http://wallet-service:3002
- IDENTITY_SERVICE_URL=http://identity-service:3000
- APP_ENV=production
depends_on:
postgres:
condition: service_healthy
networks:
- rwa-network
restart: unless-stopped
referral-service:
build: ./services/referral-service
ports:
- "3004:3004"
environment:
- DATABASE_URL=postgresql://postgres:${DB_PASSWORD}@postgres:5432/rwa_referral
- JWT_SECRET=${JWT_SECRET}
- REDIS_HOST=redis
- KAFKA_BROKERS=kafka:29092
- IDENTITY_SERVICE_URL=http://identity-service:3000
- PLANTING_SERVICE_URL=http://planting-service:3003
- APP_ENV=production
depends_on:
postgres:
condition: service_healthy
networks:
- rwa-network
restart: unless-stopped
reward-service:
build: ./services/reward-service
ports:
- "3005:3005"
environment:
- DATABASE_URL=postgresql://postgres:${DB_PASSWORD}@postgres:5432/rwa_reward
- JWT_SECRET=${JWT_SECRET}
- REDIS_HOST=redis
- KAFKA_BROKERS=kafka:29092
- IDENTITY_SERVICE_URL=http://identity-service:3000
- WALLET_SERVICE_URL=http://wallet-service:3002
- REFERRAL_SERVICE_URL=http://referral-service:3004
- APP_ENV=production
depends_on:
postgres:
condition: service_healthy
networks:
- rwa-network
restart: unless-stopped
authorization-service:
build: ./services/authorization-service
ports:
- "3006:3006"
environment:
- DATABASE_URL=postgresql://postgres:${DB_PASSWORD}@postgres:5432/rwa_authorization
- JWT_SECRET=${JWT_SECRET}
- REDIS_HOST=redis
- IDENTITY_SERVICE_URL=http://identity-service:3000
- APP_ENV=production
depends_on:
postgres:
condition: service_healthy
networks:
- rwa-network
restart: unless-stopped
leaderboard-service:
build: ./services/leaderboard-service
ports:
- "3007:3007"
environment:
- DATABASE_URL=postgresql://postgres:${DB_PASSWORD}@postgres:5432/rwa_leaderboard
- JWT_SECRET=${JWT_SECRET}
- REDIS_HOST=redis
- KAFKA_BROKERS=kafka:29092
- IDENTITY_SERVICE_URL=http://identity-service:3000
- REFERRAL_SERVICE_URL=http://referral-service:3004
- APP_ENV=production
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
networks:
- rwa-network
restart: unless-stopped
reporting-service:
build: ./services/reporting-service
ports:
- "3008:3008"
environment:
- DATABASE_URL=postgresql://postgres:${DB_PASSWORD}@postgres:5432/rwa_reporting
- JWT_SECRET=${JWT_SECRET}
- REDIS_HOST=redis
- KAFKA_BROKERS=kafka:29092
- APP_ENV=production
depends_on:
postgres:
condition: service_healthy
networks:
- rwa-network
restart: unless-stopped
backup-service:
build: ./services/backup-service
ports:
- "3009:3009"
environment:
- DATABASE_URL=postgresql://postgres:${DB_PASSWORD}@postgres-backup:5432/rwa_backup
- SERVICE_JWT_SECRET=${SERVICE_JWT_SECRET}
- APP_ENV=production
networks:
- rwa-network
restart: unless-stopped
# ============================================
# 基础设施
# ============================================
postgres:
image: postgres:16-alpine
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=${DB_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
- ./scripts/init-databases.sql:/docker-entrypoint-initdb.d/init.sql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 10
networks:
- rwa-network
restart: unless-stopped
redis:
image: redis:7-alpine
command: redis-server --requirepass ${REDIS_PASSWORD}
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"]
interval: 5s
timeout: 5s
retries: 10
networks:
- rwa-network
restart: unless-stopped
zookeeper:
image: confluentinc/cp-zookeeper:7.5.0
environment:
ZOOKEEPER_CLIENT_PORT: 2181
networks:
- rwa-network
restart: unless-stopped
kafka:
image: confluentinc/cp-kafka:7.5.0
depends_on:
- zookeeper
environment:
KAFKA_BROKER_ID: 1
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT_INTERNAL://kafka:29092
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT_INTERNAL:PLAINTEXT
KAFKA_LISTENERS: PLAINTEXT_INTERNAL://0.0.0.0:29092
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT_INTERNAL
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
KAFKA_AUTO_CREATE_TOPICS_ENABLE: "true"
networks:
- rwa-network
restart: unless-stopped
networks:
rwa-network:
driver: bridge
volumes:
postgres_data:
redis_data:
```
### 5.2 数据库初始化脚本
在 192.168.1.111 服务器上创建 `/opt/rwadurian/scripts/init-databases.sql`:
```sql
-- 创建所有微服务数据库
CREATE DATABASE rwa_identity;
CREATE DATABASE rwa_mpc;
CREATE DATABASE rwa_wallet;
CREATE DATABASE rwa_planting;
CREATE DATABASE rwa_referral;
CREATE DATABASE rwa_reward;
CREATE DATABASE rwa_authorization;
CREATE DATABASE rwa_leaderboard;
CREATE DATABASE rwa_reporting;
CREATE DATABASE rwa_backup;
```
### 5.3 环境变量文件
在 192.168.1.111 服务器上创建 `/opt/rwadurian/.env`:
```bash
# Database
DB_PASSWORD=your_secure_database_password_here
# JWT (所有服务共享)
JWT_SECRET=your_super_secure_jwt_secret_at_least_32_characters
# Redis
REDIS_PASSWORD=your_secure_redis_password
# Service JWT (服务间通信)
SERVICE_JWT_SECRET=your_service_jwt_secret_for_internal_calls
# Wallet Encryption
WALLET_ENCRYPTION_SALT=your_wallet_encryption_salt
```
## 6. 部署步骤
### 6.1 Nginx + MPC 服务器 (192.168.1.100) 配置
```bash
# ============================================
# 步骤 1: 安装 Nginx 和 Let's Encrypt
# ============================================
apt update && apt install -y nginx certbot python3-certbot-nginx
# ============================================
# 步骤 2: 创建目录结构
# ============================================
mkdir -p /etc/nginx/sites-available
mkdir -p /etc/nginx/sites-enabled
mkdir -p /etc/nginx/snippets
# ============================================
# 步骤 3: 获取 SSL 证书 (必须在配置 HTTPS 站点之前)
# ============================================
# 重要:在全新系统上,必须先获取证书,否则 Nginx 配置引用证书路径会报错
# 方式 A: 使用 standalone 模式 (推荐用于首次部署)
# 临时停止 Nginx (如果正在运行)
systemctl stop nginx
# 获取证书
certbot certonly --standalone -d rwaapi.szaiai.com
# 证书保存位置:
# /etc/letsencrypt/live/rwaapi.szaiai.com/fullchain.pem (完整证书链)
# /etc/letsencrypt/live/rwaapi.szaiai.com/privkey.pem (私钥)
# 方式 B: 使用 webroot 模式 (需要先配置 HTTP 站点)
# 1. 先配置一个简单的 HTTP 站点 (不含 SSL)
# 2. certbot certonly --webroot -w /var/www/html -d rwaapi.szaiai.com
# ============================================
# 步骤 4: 复制 Nginx 配置文件
# ============================================
# 将上面的配置文件复制到对应目录:
# - nginx.conf → /etc/nginx/nginx.conf
# - proxy-params.conf → /etc/nginx/snippets/proxy-params.conf
# - cors-params.conf → /etc/nginx/snippets/cors-params.conf
# - ssl-params.conf → /etc/nginx/snippets/ssl-params.conf
# - rwaapi.szaiai.com.conf → /etc/nginx/sites-available/rwaapi.szaiai.com.conf
# ============================================
# 步骤 5: 启用站点
# ============================================
# 禁用默认站点 (如果存在)
rm -f /etc/nginx/sites-enabled/default
# 创建软链接启用站点
ln -s /etc/nginx/sites-available/rwaapi.szaiai.com.conf /etc/nginx/sites-enabled/
# ============================================
# 步骤 6: 测试并启动 Nginx
# ============================================
# 测试配置 (此时证书已存在,不会报错)
nginx -t
# 启动 Nginx
systemctl start nginx
systemctl enable nginx
# ============================================
# 步骤 7: 配置证书自动续期
# ============================================
# Let's Encrypt 证书有效期 90 天certbot 已自动配置 systemd timer
# 验证自动续期任务:
systemctl list-timers | grep certbot
# 手动测试续期 (不会实际续期,只是测试流程):
certbot renew --dry-run
# ============================================
# 站点管理命令 (日常运维)
# ============================================
# 禁用站点: rm /etc/nginx/sites-enabled/rwaapi.szaiai.com.conf && nginx -s reload
# 启用站点: ln -s /etc/nginx/sites-available/rwaapi.szaiai.com.conf /etc/nginx/sites-enabled/ && nginx -s reload
# 重新加载: nginx -s reload
# 查看状态: systemctl status nginx
```
### 6.2 后端服务器 (192.168.1.111) 配置
```bash
# 1. 安装 Docker
curl -fsSL https://get.docker.com | sh
usermod -aG docker $USER
# 2. 安装 Docker Compose
apt install -y docker-compose-plugin
# 3. 创建部署目录
mkdir -p /opt/rwadurian
cd /opt/rwadurian
# 4. 克隆代码
git clone https://github.com/your-org/rwadurian.git .
# 5. 配置环境变量
cp .env.example .env
vim .env # 修改为生产环境配置
# 6. 创建数据库初始化脚本
mkdir -p scripts
# 将上面的 init-databases.sql 复制到 scripts/
# 7. 启动所有服务
docker compose up -d
# 8. 查看服务状态
docker compose ps
# 9. 运行数据库迁移
docker compose exec identity-service npx prisma migrate deploy
docker compose exec wallet-service npx prisma migrate deploy
docker compose exec planting-service npx prisma migrate deploy
docker compose exec referral-service npx prisma migrate deploy
docker compose exec reward-service npx prisma migrate deploy
docker compose exec leaderboard-service npx prisma migrate deploy
docker compose exec reporting-service npx prisma migrate deploy
```
### 6.3 验证部署
```bash
# 从 Nginx 服务器测试
curl -k https://rwaapi.szaiai.com/health
# 测试 API 端点
curl -k https://rwaapi.szaiai.com/api/v1/user/auto-create \
-H "Content-Type: application/json" \
-d '{"deviceId": "test-device-123"}'
# 从后端服务器直接测试
curl http://localhost:3000/api/v1/user/auto-create \
-H "Content-Type: application/json" \
-d '{"deviceId": "test-device-123"}'
```
## 7. API 端点对照表
| 前端调用路径 | Nginx 转发 | 后端服务 | 端口 |
|-------------|-----------|---------|------|
| `/api/v1/user/*` | → | Identity Service | 3000 |
| `/api/v1/auth/*` | → | Identity Service | 3000 |
| `/api/v1/wallet/*` | → | Wallet Service | 3002 |
| `/api/v1/trading/*` | → | Wallet Service | 3002 |
| `/api/v1/deposit/*` | → | Wallet Service | 3002 |
| `/api/v1/mining/*` | → | Reward Service | 3005 |
| `/api/v1/reward/*` | → | Reward Service | 3005 |
| `/api/v1/ranking/*` | → | Leaderboard Service | 3007 |
| `/api/v1/leaderboard/*` | → | Leaderboard Service | 3007 |
| `/api/v1/planting/*` | → | Planting Service | 3003 |
| `/api/v1/referral/*` | → | Referral Service | 3004 |
| `/api/v1/community/*` | → | Referral Service | 3004 |
| `/api/v1/telemetry/*` | → | Reporting Service | 3008 |
| `/api/v1/report/*` | → | Reporting Service | 3008 |
## 8. 监控与运维
### 8.1 查看 Nginx 日志
```bash
# 访问日志
tail -f /var/log/nginx/access.log
# 错误日志
tail -f /var/log/nginx/error.log
# 过滤特定服务请求
grep "/api/v1/user" /var/log/nginx/access.log | tail -100
```
### 8.2 查看服务日志
```bash
# ========================================
# 192.168.1.100 (Nginx + MPC 服务器) 日志
# ========================================
# MPC-System 日志
tail -f /var/log/mpc-system/mpc.log
journalctl -u mpc-system -f
# ========================================
# 192.168.1.111 (后端服务器) 日志
# ========================================
# 查看所有服务日志
docker compose logs -f
# 查看特定服务日志
docker compose logs -f identity-service
docker compose logs -f mpc-service
docker compose logs -f wallet-service
# 查看最近 100 行
docker compose logs --tail=100 identity-service
```
### 8.3 服务健康检查
```bash
# ========================================
# 192.168.1.100 (Nginx + MPC 服务器) 健康检查
# ========================================
curl http://192.168.1.100:4000/health # MPC-System
curl https://rwaapi.szaiai.com/health # Nginx 反向代理
# ========================================
# 192.168.1.111 (后端服务器) 健康检查
# ========================================
# 检查所有服务状态
docker compose ps
# 检查各微服务健康
curl http://192.168.1.111:3000/health # Identity
curl http://192.168.1.111:3001/health # MPC Service (NestJS)
curl http://192.168.1.111:3002/health # Wallet
curl http://192.168.1.111:3003/health # Planting
curl http://192.168.1.111:3004/health # Referral
curl http://192.168.1.111:3005/health # Reward
curl http://192.168.1.111:3007/health # Leaderboard
curl http://192.168.1.111:3008/health # Reporting
```
### 8.4 重启服务
```bash
# 重启单个服务
docker compose restart identity-service
# 重启所有服务
docker compose restart
# 重建并重启
docker compose up -d --build identity-service
```
## 9. 常见问题
### Q1: 502 Bad Gateway
- 检查后端服务是否运行: `docker compose ps`
- 检查 Nginx 到 192.168.1.111 网络是否通: `ping 192.168.1.111`
- 检查端口是否开放: `telnet 192.168.1.111 3000`
### Q2: CORS 错误
- 确认 Nginx 配置中 CORS 头已正确设置
- 检查 OPTIONS 预检请求是否返回 204
### Q3: SSL 证书问题
- 检查 Let's Encrypt 证书: `ls -la /etc/letsencrypt/live/rwaapi.szaiai.com/`
- 测试 SSL 连接: `openssl s_client -connect rwaapi.szaiai.com:443`
- 检查证书有效期: `openssl x509 -in /etc/letsencrypt/live/rwaapi.szaiai.com/fullchain.pem -noout -dates`
- 手动续期证书: `certbot renew`
- 查看续期日志: `journalctl -u certbot.timer`
### Q4: 服务间通信失败
- 检查 Docker 网络: `docker network inspect rwa-network`
- 检查服务名解析: `docker compose exec identity-service ping wallet-service`
### Q5: MPC-System 连接失败
- 检查 MPC-System 服务状态: `systemctl status mpc-system` (在 192.168.1.100 上)
- 检查 MPC-System 健康: `curl http://192.168.1.100:4000/health`
- 检查防火墙规则是否允许 192.168.1.111 访问 4000 端口
- 检查 mpc-service 环境变量 `MPC_SYSTEM_URL` 是否正确设置为 `http://192.168.1.100:4000`
- 查看 MPC-System 日志: `tail -f /var/log/mpc-system/mpc.log`
### Q6: TSS 密钥生成/签名超时
- MPC 操作可能需要较长时间,检查超时配置
- 确保网络延迟在合理范围内: `ping 192.168.1.100`
- 检查 MPC-System 资源使用: `htop``top`
---
**最后更新**: 2025-12-01
**维护者**: RWA Team