# GCP Deployment

Deploy Monetarie PIX on Google Cloud Platform, the reference deployment environment. Monetarie PIX was built and tested on GCP southamerica-east1 (Sao Paulo).

## Prerequisites

- GCP project with billing enabled
- `gcloud` CLI configured
- `kubectl` configured
- Domain with DNS managed in Cloud DNS or external

## Reference Architecture

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

    subgraph VPC [VPC Network]
        GKE --> CSQL[(Cloud SQL<br/>PostgreSQL 16)]
        GKE --> MEM[(Memorystore<br/>Redis 7)]
        GKE --> NATS[NATS VMs<br/>3-node cluster]
    end

    GKE -->|Outbound| BACEN[BACEN RSFN]
```

## Infrastructure Setup

### GKE Cluster

```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 DIRECT PRIVATE IP
Use Cloud SQL private IP directly (`10.140.241.2`) instead of Cloud SQL Proxy. The proxy rate-limits to 1000 connections/minute, which conflicts with high connection pools (POOL_SIZE=200 x 4 repos).
:::

Key configuration:

| Parameter | Value |
|-----------|-------|
| `max_connections` | 6000 |
| Private IP | `10.140.241.2` |
| POOL_SIZE | 200 per repo |

### Memorystore Redis

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

### NATS Cluster (Compute Engine)

```bash
# Deploy 3 VMs for NATS JetStream cluster
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 nodes: `10.10.40.5:4222`, `10.10.40.7:4222`, `10.10.40.4:4222`

## Container Build (Cloud Build)

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

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

# Admin Frontend
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
Always pass `--substitutions=SHORT_SHA=...` when running `gcloud builds submit` manually. The variable is empty outside Cloud Build triggers.
:::

## Kubernetes Deployment

### 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"
```

### Deploy

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

### Database Migration

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

## Ingress (Traefik)

Monetarie uses Traefik as the ingress controller with 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
```

## Cost Estimate (southamerica-east1)

| Resource | Spec | Monthly (USD) |
|----------|------|---------------|
| GKE Cluster | Control plane | ~$73 |
| GKE Nodes (3x) | e2-standard-8 | ~$580 |
| Cloud SQL | db-custom-8-32768, Regional | ~$700 |
| Memorystore | 4 GB Redis | ~$200 |
| NATS VMs (3x) | e2-standard-4 | ~$290 |
| Cloud Load Balancer | Standard | ~$25 |
| **Total** | | **~$1,868** |

## Expected Outcome

After completing this deployment:

- GKE cluster in southamerica-east1 with 3 nodes
- Cloud SQL with private IP and max_connections=6000
- Memorystore Redis for caching
- NATS 3-node JetStream cluster
- Traefik ingress with TLS at `pixapi-dev.fluxiq.com.br`
- All services healthy and processing transactions
