Files
danyang-match/docs/OPS.md
T

229 lines
5.4 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.
# 丹阳公益婚恋服务平台 — 运维手册
> 本文档面向运维人员,说明如何部署、监控、备份和恢复平台。
---
## 一、系统架构
```
┌─────────────────────────────────────────────────┐
│ Nginx (HTTPS) │
│ :80 → :443 │ /api/ → Backend │ /ws/ → WS │
│ /admin/ → Admin Web SPA │
└──────────────┬──────────────────────────────────┘
│
┌──────────┼──────────┐
▼ ▼ ▼
Backend PostgreSQL Redis
:8080 :5432 :6379
│ │ │
│ MinIO (对象存储) │
│ :9000/:9001 │
└──────────┴──────────┘
```
---
## 二、快速部署
### 2.1 前置条件
- Docker 20+ / Docker Compose v2+
- HTTPS 证书(Let's Encrypt 或自建 CA)
- 至少 2核4G 云服务器
### 2.2 准备密钥
```bash
# 复制环境变量模板
cp infrastructure/.env.example infrastructure/.env
# 生成安全密钥
openssl rand -hex 32 > infrastructure/.env # 替换 ENCRYPTION_KEY
# 修改 .env 中的以下必填项:
# DB_PASSWORD / REDIS_PASSWORD
# JWT_ACCESS_SECRET / JWT_REFRESH_SECRET
# CHECKIN_TOKEN_SECRET / ENCRYPTION_KEY
# MINIO_ACCESS_KEY / MINIO_SECRET_KEY
# WECHAT_APP_ID / WECHAT_APP_SECRET
```
### 2.3 准备证书
```bash
# 创建证书目录
mkdir -p infrastructure/certs
# 方式1:Let's Encrypt(推荐)
certbot certonly --standalone -d match.danyang.gov.cn
cp /etc/letsencrypt/live/match.danyang.gov.cn/fullchain.pem infrastructure/certs/
cp /etc/letsencrypt/live/match.danyang.gov.cn/privkey.pem infrastructure/certs/
chmod 600 infrastructure/certs/privkey.pem
# 方式2:自签证书(测试环境)
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout infrastructure/certs/privkey.pem \
-out infrastructure/certs/fullchain.pem \
-subj "/CN=match.danyang.gov.cn"
```
### 2.4 启动服务
```bash
cd infrastructure
# 生产环境
docker compose -f docker-compose.prod.yml up -d
# 验证
./scripts/health-check.sh
```
---
## 三、备份策略
### 3.1 自动备份(每日凌晨 2:00)
```bash
# 添加到 crontab
0 2 * * * cd /opt/danyang-match/infrastructure && ./scripts/backup.sh >> /var/log/daily-backup.log 2>&1
```
### 3.2 手动备份
```bash
cd infrastructure
./scripts/backup.sh # 备份默认库
./scripts/backup.sh danyang_match # 备份指定库
```
### 3.3 备份保留策略
- 自动保留最近 **30天** 的备份
- 最多保留 **10份** 备份文件
- 备份文件存储在 `infrastructure/backups/` 目录(挂载到持久卷)
---
## 四、恢复流程
### 4.1 全库恢复
```bash
cd infrastructure
./scripts/restore.sh backups/danyang_match_20260828_143000.sql.gz
```
### 4.2 单表恢复
```bash
# 先导出需要恢复的表
docker exec danyang-match-postgres \
pg_dump -U danyang -d danyang_match --table reviews > review_backup.sql
# 恢复
gunzip -c review_backup.sql | psql -U danyang -d danyang_match
```
---
## 五、部署与回滚
### 5.1 部署新版本
```bash
cd infrastructure
./scripts/deploy.sh v1.3.0 deploy
```
### 5.2 回滚到上一版本
```bash
./scripts/deploy.sh rollback
```
### 5.3 维护模式
```bash
# 开启维护模式(返回 503)
curl -H "X-Maintenance-Mode: 1" https://match.danyang.gov.cn/
# 关闭维护模式
# 只需重启 nginx 容器即可
docker compose -f docker-compose.prod.yml restart nginx
```
---
## 六、监控指标
### 6.1 健康检查
```bash
./scripts/health-check.sh --detail
```
### 6.2 关键指标
| 指标 | 检查方法 | 告警阈值 |
|---|---|---|
| PostgreSQL 可用 | `pg_isready` | 任何失败 |
| Redis 可用 | `redis-cli ping` | 任何失败 |
| 后端健康 | `/api/v1/health/live` | 5分钟连续失败 |
| 磁盘使用 | `docker system df` | >80% |
| 内存使用 | `docker stats` | >90% |
### 6.3 日志查看
```bash
# Backend 日志
docker logs -f danyang-match-backend
# Nginx 访问日志
docker logs danyang-match-nginx
# 完整堆栈
docker compose -f docker-compose.prod.yml logs -f --tail=100
```
---
## 七、安全注意事项
1. **密钥不进 Git** — `.env` 和 `secrets/` 目录已在 `.gitignore` 中排除
2. **PostgreSQL 仅内网** — 生产配置绑定 `127.0.0.1:5432`,不对外暴露
3. **Redis 设密码** — `requirepass` 必须在 `.env` 中配置
4. **MinIO 图片私有** — 通过 Signed URL 访问,不公开 Bucket
5. **HTTPS 强制** — HTTP 全部重定向到 HTTPS
6. **定期轮换密钥** — 建议每季度轮换 JWT Secret 和加密密钥
---
## 八、应急响应
### 8.1 数据泄露
```
发现 → 隔离(停止相关容器)→ 评估影响 → 修复漏洞 → 记录事件 → 依法报告 → 复盘
```
### 8.2 账号被封禁
```bash
# 紧急解封
docker exec -it danyang-match-postgres psql -U danyang -d danyang_match \
-c "UPDATE operators SET status='normal' WHERE id='xxx';"
```
### 8.3 服务宕机
```bash
# 重启所有服务
docker compose -f docker-compose.prod.yml restart
# 如数据库损坏,从备份恢复
./scripts/restore.sh backups/latest_backup.sql.gz
```