# GCP 部署

在 Google Cloud Platform 上部署 Monetarie PIX，这是参考部署环境。Monetarie PIX 在 GCP southamerica-east1（圣保罗）上构建和测试。

## 前提条件

- 已启用计费的 GCP 项目
- `gcloud` CLI 已配置
- `kubectl` 已配置
- 在 Cloud DNS 或外部管理的域名 DNS

## 参考架构

```mermaid
graph TB
    DNS[Cloud DNS] --> LB[Cloud Load Balancer]
    LB --> GKE[GKE 集群<br/>3x e2-standard-8]

    subgraph VPC [VPC 网络]
        GKE --> CSQL[(Cloud SQL<br/>PostgreSQL 16)]
        GKE --> MEM[(Memorystore<br/>Redis 7)]
        GKE --> NATS[NATS VMs<br/>3 节点集群]
    end

    GKE -->|出站| BACEN[BACEN RSFN]
```

## 基础设施设置

### GKE 集群

```bash
gcloud container clusters create fluxiq-dev \
  --region=southamerica-east1 \
  --num-nodes=3 \
  --machine-type=e2-standard-8 \
  --enable-ip-alias \
  --network=monetarie-vpc \
  --subnetwork=monetarie-nodes
```

### Cloud SQL PostgreSQL

```bash
gcloud sql instances create monetarie-pix-db \
  --database-version=POSTGRES_16 \
  --tier=db-custom-8-32768 \
  --region=southamerica-east1 \
  --network=monetarie-vpc \
  --no-assign-ip \
  --availability-type=REGIONAL
```

::: tip 直接私有 IP
使用 Cloud SQL 私有 IP 直接连接（`10.140.241.2`），而不是 Cloud SQL Proxy。Proxy 限速为每分钟 1000 个连接，这与高连接池（POOL_SIZE=200 x 4 repos）冲突。
:::

关键配置：

| 参数 | 值 |
|------|-----|
| `max_connections` | 6000 |
| 私有 IP | `10.140.241.2` |
| POOL_SIZE | 每个 repo 200 |

### Memorystore Redis

```bash
gcloud redis instances create monetarie-pix-redis \
  --size=4 \
  --region=southamerica-east1 \
  --network=monetarie-vpc \
  --redis-version=redis_7_0
```

### NATS 集群 (Compute Engine)

```bash
# 为 NATS JetStream 集群部署 3 个 VM
for i in 1 2 3; do
  gcloud compute instances create nats-dev-$i \
    --zone=southamerica-east1-a \
    --machine-type=e2-standard-4 \
    --network=monetarie-vpc
done
```

NATS 节点：`10.10.40.5:4222`、`10.10.40.7:4222`、`10.10.40.4:4222`

## 容器构建 (Cloud Build)

```bash
SHORT_SHA=$(git rev-parse --short HEAD)

# 后端
gcloud builds submit --config=backend/cloudbuild.yaml \
  --substitutions=SHORT_SHA=$SHORT_SHA \
  --machine-type=E2_HIGHCPU_8 \
  --region=southamerica-east1 backend/

# 管理前端
gcloud builds submit --config=frontend/admin/cloudbuild.yaml \
  --substitutions=SHORT_SHA=$SHORT_SHA \
  --machine-type=E2_HIGHCPU_8 \
  --region=southamerica-east1 frontend/admin/
```

::: warning SHORT_SHA
手动运行 `gcloud builds submit` 时务必传递 `--substitutions=SHORT_SHA=...`。该变量在 Cloud Build 触发器之外为空。
:::

## Kubernetes 部署

### Secrets

```bash
kubectl create secret generic db-credentials -n pix \
  --from-literal=database-url="postgres://monetarie_prod:PASS@10.140.241.2:5432/monetarie" \
  --from-literal=secret-key-base="$(mix phx.gen.secret)"

kubectl create secret generic monetarie-shared-jwt-secret -n pix \
  --from-literal=jwt-secret="shared-with-core-banking"
```

### 部署

```bash
kubectl apply -f deploy/backend.yaml
kubectl apply -f deploy/admin-frontend.yaml
```

### 数据库迁移

```bash
kubectl exec -n pix deployment/pix-backend -- bin/monetarie_pix eval "Shared.Release.migrate()"
```

## Ingress (Traefik)

Monetarie 使用 Traefik 作为 Ingress 控制器并配合 TLS：

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: pix-backend-ingress
  namespace: pix
spec:
  tls:
    - hosts: [pixapi-dev.fluxiq.com.br]
      secretName: monetarie-dev-tls
  rules:
    - host: pixapi-dev.fluxiq.com.br
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: pix-backend
                port:
                  number: 4003
```

## 成本估算 (southamerica-east1)

| 资源 | 规格 | 月费 (USD) |
|------|------|------------|
| GKE 集群 | 控制平面 | ~$73 |
| GKE 节点 (3x) | e2-standard-8 | ~$580 |
| Cloud SQL | db-custom-8-32768, 区域级 | ~$700 |
| Memorystore | 4 GB Redis | ~$200 |
| NATS VMs (3x) | e2-standard-4 | ~$290 |
| Cloud Load Balancer | 标准 | ~$25 |
| **合计** | | **~$1,868** |

## 预期结果

完成此部署后：

- GKE 集群在 southamerica-east1 运行，具有 3 个节点
- Cloud SQL 具有私有 IP 和 max_connections=6000
- Memorystore Redis 用于缓存
- NATS 3 节点 JetStream 集群
- Traefik Ingress 具有 TLS，域名 `pixapi-dev.fluxiq.com.br`
- 所有服务健康并处理交易
