# 本地部署

在裸机或虚拟化基础设施上部署 Monetarie PIX，适用于需要完全数据主权的受监管环境。

## 前提条件

- 虚拟化平台（ProxMox、VMware、Hyper-V）或裸机服务器
- 具有防火墙功能的网络基础设施
- 负载均衡器（HAProxy、nginx 或硬件负载均衡器）
- 用于 BACEN 连接的 ICP-Brasil 证书

## 参考架构

```mermaid
graph TB
    INET[互联网] --> FW[防火墙]
    FW --> HAP[HAProxy<br/>TLS 终止]
    HAP --> APP1[应用服务器 1<br/>Monetarie PIX]
    HAP --> APP2[应用服务器 2<br/>Monetarie PIX]

    APP1 --> PG_P[(PostgreSQL 主节点)]
    APP2 --> PG_P
    PG_P --> PG_R[(PostgreSQL 副本)]

    APP1 --> REDIS[Redis Sentinel<br/>3 节点]
    APP2 --> REDIS

    APP1 --> NATS1[NATS 节点 1]
    APP2 --> NATS2[NATS 节点 2]
    NATS1 --> NATS3[NATS 节点 3]
```

## 硬件要求

| 角色 | CPU | 内存 | 磁盘 | 数量 |
|------|-----|------|------|------|
| 应用服务器 | 8 核 | 32 GB | 100 GB SSD | 2 |
| PostgreSQL 主节点 | 8 核 | 64 GB | 1 TB NVMe | 1 |
| PostgreSQL 副本 | 8 核 | 64 GB | 1 TB NVMe | 1 |
| Redis Sentinel | 4 核 | 8 GB | 50 GB SSD | 3 |
| NATS 服务器 | 4 核 | 16 GB | 200 GB SSD | 3 |
| HAProxy | 4 核 | 8 GB | 50 GB SSD | 2 |

## 虚拟机设置 (ProxMox 示例)

### 创建虚拟机

```bash
# 应用服务器
qm create 101 --name pix-app-1 --cores 8 --memory 32768 --net0 virtio,bridge=vmbr0
qm create 102 --name pix-app-2 --cores 8 --memory 32768 --net0 virtio,bridge=vmbr0

# PostgreSQL
qm create 201 --name pix-db-primary --cores 8 --memory 65536 --net0 virtio,bridge=vmbr0
qm create 202 --name pix-db-replica --cores 8 --memory 65536 --net0 virtio,bridge=vmbr0
```

### 安装依赖 (Ubuntu 22.04)

```bash
# Docker
curl -fsSL https://get.docker.com | sh

# 或直接安装 Elixir 用于 systemd 部署
wget https://packages.erlang-solutions.com/erlang-solutions_2.0_all.deb
dpkg -i erlang-solutions_2.0_all.deb
apt-get update && apt-get install -y esl-erlang elixir
```

## PostgreSQL with Patroni

```yaml
# patroni.yml
scope: monetarie-pix
namespace: /service/
name: node1

restapi:
  listen: 0.0.0.0:8008

postgresql:
  listen: 0.0.0.0:5432
  data_dir: /var/lib/postgresql/16/main
  parameters:
    max_connections: 6000
    shared_buffers: 16GB
    effective_cache_size: 48GB
    work_mem: 64MB
```

## Redis Sentinel

```conf
# sentinel.conf (在每个 3 个节点上)
sentinel monitor monetarie-pix-redis 10.0.1.10 6379 2
sentinel down-after-milliseconds monetarie-pix-redis 5000
sentinel failover-timeout monetarie-pix-redis 60000
```

## NATS 集群

```conf
# nats-server.conf (每个节点)
port: 4222
jetstream {
    store_dir: /data/nats
    max_mem: 4G
    max_file: 100G
}
cluster {
    name: monetarie-pix
    listen: 0.0.0.0:6222
    routes: [
        nats://10.0.2.1:6222
        nats://10.0.2.2:6222
        nats://10.0.2.3:6222
    ]
}
```

## 应用部署 (Systemd)

### 构建 Release

```bash
cd backend
MIX_ENV=prod mix deps.get
MIX_ENV=prod mix release
```

### Systemd 单元

```ini
# /etc/systemd/system/monetarie-pix.service
[Unit]
Description=Monetarie PIX Backend
After=network.target postgresql.service

[Service]
Type=exec
User=monetarie
Group=monetarie
WorkingDirectory=/opt/monetarie/pix
ExecStart=/opt/monetarie/pix/bin/monetarie_pix start
ExecStop=/opt/monetarie/pix/bin/monetarie_pix stop
Restart=on-failure
RestartSec=5
EnvironmentFile=/opt/monetarie/pix/.env
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
```

```bash
systemctl enable monetarie-pix
systemctl start monetarie-pix
```

## HAProxy 配置

```conf
frontend https_frontend
    bind *:443 ssl crt /etc/haproxy/certs/monetarie.pem
    default_backend pix_backend

backend pix_backend
    balance roundrobin
    option httpchk GET /health
    http-check expect status 200
    server app1 10.0.1.1:4003 check inter 5s fall 3 rise 2
    server app2 10.0.1.2:4003 check inter 5s fall 3 rise 2
```

## 防火墙规则

```bash
# 允许 HTTPS 入站
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# 允许内部服务
iptables -A INPUT -s 10.0.0.0/8 -p tcp --dport 4001:4003 -j ACCEPT
iptables -A INPUT -s 10.0.0.0/8 -p tcp --dport 5432 -j ACCEPT
iptables -A INPUT -s 10.0.0.0/8 -p tcp --dport 6379 -j ACCEPT
iptables -A INPUT -s 10.0.0.0/8 -p tcp --dport 4222 -j ACCEPT

# 允许 BACEN 出站
iptables -A OUTPUT -p tcp --dport 16522 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 17522 -j ACCEPT
```

## 预期结果

完成此部署后：

- 2 个应用服务器位于 HAProxy 之后，具有健康检查的负载均衡
- PostgreSQL 主副本具有通过 Patroni 的自动故障转移
- Redis Sentinel 实现缓存高可用
- NATS 3 节点 JetStream 集群
- 所有流量使用 TLS 加密
- 防火墙限制访问仅限必需端口
