# PPanel 香港区新 AWS 账号部署说明

本目录用于在 **新 AWS 账号** 中按 **香港区 `ap-east-1`** 重建一套全新空环境。

目标架构：

`DNS -> ALB -> WAF -> EC2(Nginx + ppanel-server + Redis + observability) -> RDS MySQL`

## 1. 资源清单

按下面顺序创建资源：

1. VPC
2. 2 个公有子网 + 2 个私有子网
3. Internet Gateway
4. 公有 / 私有路由表
5. 安全组
6. RDS MySQL
7. EC2 本机 Redis Docker
8. EC2
9. ACM 证书
10. ALB + Target Group
11. WAF Web ACL
12. 平行环境域名

建议命名：

- VPC: `ppanel-hk-prod`
- EC2: `ppanel-app-hk-01`
- RDS: `ppanel-mysql-hk`
- Redis container: `hifast-redis`
- ALB: `ppanel-alb-hk`
- WAF: `ppanel-waf-hk`

## 2. 默认规格

### EC2

- Region: `ap-east-1`
- OS: Ubuntu 24.04 LTS
- Instance type: `t4g.large` 起步
- Disk: `gp3 80GB`
- Public subnet: 是
- IAM Role: 允许读取 CloudWatch / SSM（如使用）
- 如果要在 AWS EC2 本机执行 S3 备份：额外允许写入专用备份桶

### RDS MySQL

- Engine: MySQL 8.0
- Class: `db.r7g.xlarge`
- Storage: `gp3 100GB`
- DB name: `hifast`
- Username: `admin`
- Public access: `No`
- Charset: `utf8mb4`
- Backup: `7-14 days`

### Redis

- 部署位置：业务 EC2 本机
- 部署方式：Docker
- 版本：`redis:8.2.1`
- 监听：`0.0.0.0:6379`
- 应用连接：`127.0.0.1:6379`
- 安全组：仅对白名单备用节点或同机应用开放

## 3. 网络与安全组

### 子网布局

- `public-a`, `public-b`: ALB / EC2
- `private-a`, `private-b`: RDS

### 安全组建议

#### `sg-alb`

- Inbound
  - `80/tcp` from `0.0.0.0/0`
  - `443/tcp` from `0.0.0.0/0`
- Outbound
  - `80/tcp` to `sg-ec2`

#### `sg-ec2`

- Inbound
  - `80/tcp` from `sg-alb`
  - `22/tcp` from `你的固定运维 IP`
- Outbound
  - all

说明：

- 应用容器监听 `127.0.0.1:8080`
- EC2 对外只让 Nginx 监听 `80`
- Grafana / Prometheus / Tempo 仅监听 `127.0.0.1`

#### `sg-rds`

- Inbound
  - `3306/tcp` from `sg-ec2`

#### `sg-ec2` 额外说明

- 如果需要外部备用节点复制 Redis，再额外放行：
  - `6379/tcp` from `104.238.220.230/32`

## 4. ALB / Target Group / 健康检查

### Target Group

- Type: `Instance`
- Protocol: `HTTP`
- Port: `80`
- Health check path: `/v1/common/heartbeat`
- Success code: `200`

这个路径已由项目现有接口提供，无需额外改代码。

### ALB 监听器

- `80` -> redirect to `443`
- `443` -> forward 到 target group

### ACM

- 在 `ap-east-1` 申请证书
- 先给平行环境域名，例如：
  - `api-new.hifast.biz`
  - `logs-new.hifast.biz`

## 5. WAF 规则

首版至少启用：

1. `AWSManagedRulesCommonRuleSet`
2. `AWSManagedRulesKnownBadInputsRuleSet`
3. `AWSManagedRulesAmazonIpReputationList`
4. 全站 rate-based rule
5. 针对高风险路径的 rate-based rule

建议的第一版限流：

- 全站：每 IP `2000 / 5 分钟`
- `/v1/public/user/subscribe`：每 IP `300 / 5 分钟`
- 登录 / 注册 / 验证码接口：每 IP `100 / 5 分钟`

节点上报接口建议后续补：

- `/v1/server/status`
- `/v1/server/online`
- `/v1/server/traffic`

优先用节点出口 IP 白名单；没有固定出口 IP 的节点暂时保留 `secret_key`，但不要把它当成唯一防线。

## 6. EC2 文件落地

在 EC2 上建议使用：

- 应用目录：`/opt/ppanel`
- Nginx 配置：`/etc/nginx/sites-available/ppanel-api.conf`

需要上传这些文件 / 目录：

- `docker-compose.cloud.yml`
- `deploy/aws/ap-east-1/configs/ppanel.yaml.example` -> 重命名为 `configs/ppanel.yaml`
- `deploy/aws/ap-east-1/nginx/ppanel-api.conf`
- `grafana/`
- `loki/`
- `prometheus/`
- `tempo/`
- `.env.example` -> 重命名为 `.env`

目标目录示例：

```text
/opt/ppanel/
  docker-compose.cloud.yml
  .env
  configs/ppanel.yaml
  grafana/
  loki/
  prometheus/
  tempo/
  logs/
  cache/
  tempo_data/
```

## 7. 应用配置

基线模板见：

- [`configs/ppanel.yaml.example`](./configs/ppanel.yaml.example)
- [`nginx/ppanel-api.conf`](./nginx/ppanel-api.conf)

关键值必须替换：

- `MySQL.Addr`
- `MySQL.Password`
- `Redis.Host`
- `Redis.Pass`
- `JwtAuth.AccessSecret`
- `Administrator.Email`
- `Administrator.Password`
- `AppSignature.AppSecrets.*`
- `device.security_secret`
- `Site.Host`
- `Site.SiteName`

Redis 约定保持不变：

- 业务缓存：DB `0`
- Asynq：DB `5`（代码内部已固定使用）

## 8. 部署步骤

### 8.1 初始化 EC2

把脚本上传到 EC2 后执行：

## 9. 104 灾备节点常用运维脚本

如果你要在 `104.238.220.230` 上执行数据迁移、主从重拉、主库提升，可以直接复用仓库里的这几份脚本：

- 数据导出 / 导入交互工具：
  - [`deploy/scripts/hifast_data_sync_tool.sh`](/Users/Apple/code_vpn/vpn/ppanel-server/deploy/scripts/hifast_data_sync_tool.sh)
- MySQL 主从运维工具：
  - [`deploy/scripts/mysql_replica_ops.sh`](/Users/Apple/code_vpn/vpn/ppanel-server/deploy/scripts/mysql_replica_ops.sh)
- Redis 主从运维工具：
  - [`deploy/scripts/redis_replica_ops.sh`](/Users/Apple/code_vpn/vpn/ppanel-server/deploy/scripts/redis_replica_ops.sh)
- 统一总入口：
  - [`deploy/scripts/hifast_data_sync_tool.sh`](/Users/Apple/code_vpn/vpn/ppanel-server/deploy/scripts/hifast_data_sync_tool.sh)
- 主从运维环境模板：
  - [`deploy/aws/ap-east-1/configs/replica-ops.env.example`](/Users/Apple/code_vpn/vpn/ppanel-server/deploy/aws/ap-east-1/configs/replica-ops.env.example)

### 9.1 数据迁移工具

支持：

- 备份 MySQL 到 S3
- 备份 Redis 到 S3
- 从正式库导出 MySQL `sql.gz`
- 把 `sql.gz` 导入 AWS RDS
- 从正式 Redis 导出 `RDB`
- 将 `RDB` 导入 Docker Redis 或宿主机 Redis
- 查看 MySQL / Redis 当前主从状态
- 强制重拉 MySQL / Redis 主从
- 把 MySQL / Redis 从库提升为可写主库

示例：

```bash
bash deploy/scripts/hifast_data_sync_tool.sh /root/replica-ops.env
```

```bash
chmod +x deploy/scripts/bootstrap_aws_ec2.sh
sudo APP_DIR=/opt/ppanel deploy/scripts/bootstrap_aws_ec2.sh
```

### 8.2 安装 Nginx 配置

```bash
sudo cp deploy/aws/ap-east-1/nginx/ppanel-api.conf /etc/nginx/sites-available/ppanel-api.conf
sudo ln -sf /etc/nginx/sites-available/ppanel-api.conf /etc/nginx/sites-enabled/ppanel-api.conf
sudo nginx -t
sudo systemctl reload nginx
```

### 8.3 启动容器

```bash
cd /opt/ppanel
docker compose -f docker-compose.cloud.yml up -d
```

### 8.4 预检

```bash
chmod +x deploy/scripts/preflight_aws_hk.sh
APP_DIR=/opt/ppanel \
RDS_HOST=<new-rds-endpoint> \
REDIS_HOST=127.0.0.1 \
deploy/scripts/preflight_aws_hk.sh
```

## 9. 平行环境验证

先验证 `api-new.hifast.biz`，不要直接切正式域名。

必测项：

1. `ALB target` 为 healthy
2. `GET /v1/common/heartbeat` 返回 200
3. 管理员登录
4. 用户注册 / 登录
5. 订阅查询
6. 节点上报 `/v1/server/status`
7. 本机 Redis 可写缓存
8. Asynq 可入队并消费

## 10. 正式切换

切换前检查：

1. ALB 5xx 为 0
2. EC2 CPU / Memory 正常
3. RDS CPU / Connections 正常
4. 本机 Redis CPU / Connections / Memory 正常
5. WAF 已挂到 ALB
6. EC2 安全组没有对公网放 `8080/3333/9090/4317`

切换方式：

1. 保持新环境先跑平行域名
2. 正式域名切到新 ALB
3. 观察至少 1 小时
4. 确认无误后再处理旧环境

## 11. 监控建议

至少建这些 CloudWatch / Grafana 观测项：

- ALB `RequestCount`, `HTTPCode_ELB_5XX_Count`, `TargetResponseTime`
- EC2 `CPUUtilization`, `NetworkIn`, `NetworkOut`, `StatusCheckFailed`
- RDS `CPUUtilization`, `DatabaseConnections`, `ReadLatency`, `WriteLatency`
- Redis 容器 CPU / Memory / restart count

## 12. 这次方案的边界

本目录交付的是：

- 香港区新账号的部署模板
- 新空环境启动与验证流程
- ALB / WAF / EC2 / RDS / 本机 Redis 的落地约定

不包含：

- 旧数据迁移
- Terraform / CloudFormation 自动建资源
- Redis 托管版改造
- 多活 / 自动扩缩容

## 13. S3 备份补强

当前已落地的 S3 备份桶：

- `hifast-prod-backups-200810848252-ap-east-1`

建议与现网结合方式：

1. `RDS automated backup` 继续保留，作为第一层恢复能力
2. `104` 外部 MySQL 从库执行逻辑备份并上传到 S3，作为第二层可下载备份
3. `104` 外部 Redis 从库按需导出 `RDB` 到 S3，补齐缓存类灾备材料

仓库中已补充：

- 环境变量模板：[`configs/backup-to-s3.env.example`](./configs/backup-to-s3.env.example)
- MySQL 备份脚本：[`../../scripts/mysql_backup_to_s3.sh`](../../scripts/mysql_backup_to_s3.sh)
- Redis 备份脚本：[`../../scripts/redis_rdb_backup_to_s3.sh`](../../scripts/redis_rdb_backup_to_s3.sh)

建议把 MySQL 备份脚本优先部署到 `104`，因为它直接连接本地只读从库，对 AWS 主库扰动最小。
