Pular para o conteúdo principal

Deploy

Status: HML pronto pra aplicar via Terraform. Prod em skeleton.

Visão geral

Infraestrutura no GCP gerenciada com Terraform. Arquitetura atual: single-VM com Docker Compose (GCE VM hospeda tudo — Postgres, Redis, 10 APIs Node, nginx servindo as 5 SPAs).

Esta topologia substitui a arquitetura managed (Cloud Run + Cloud SQL + Memorystore + LB) que a gente tentou inicialmente e foi bloqueada por org policies da org pai (iam.allowedPolicyMemberDomains impedindo allUsers em IAM, o que é requisito do Cloud Run público). O pivô pra VM foi pragmático: acesso público vira um firewall rule de rede (não IAM), que a policy não alcança.

Domínio atual: onlyfordev.xyz — temporário descartável. Quando chegar o domínio final, trocar em environments/*/terraform.tfvars + environment.prod.ts das SPAs + docker/.env (CORS_ORIGINS, SESSION_COOKIE_DOMAIN).

Subdomínios

Todos apontam pra uma única VM via DNS A record. Nginx dentro da VM roteia por Host header.

HostServe
cms.onlyfordev.xyzSPA cms-web (estática, nginx root)
hub.onlyfordev.xyzSPA hub-web
admin.onlyfordev.xyzSPA adm-web
editor.onlyfordev.xyzSPA cms-editor (iframe Puck)
media.onlyfordev.xyzSPA cms-media (iframe galeria)
cms-api.onlyfordev.xyzProxy → container cms-api:3000
hub-api.onlyfordev.xyzProxy → hub-api:3100 (+ SSE /events)
platform-api.onlyfordev.xyzProxy → platform-api:3200
tenant-api.onlyfordev.xyzProxy → tenant-api:3201
user-api.onlyfordev.xyzProxy → user-api:3202 (login, sessão)
webhook.onlyfordev.xyzProxy → hub-webhook:3002
monitor.onlyfordev.xyzProxy → hub-monitor:3010
render.onlyfordev.xyzProxy → cms-renderer:3001 (SSR sites)

Arquitetura de compute

WorkloadOnde roda
APIs Node (10)Containers Docker numa única GCE VM
Workers BullMQ (hub-runner, hub-scheduler)Containers no mesmo compose
SPAs (5)Build estático montado como volume no nginx
NginxContainer — reverse proxy + SSL termination
CertbotContainer companion (renovação automática)

Dados

RecursoOnde
PostgreSQL 16Container Postgres com volume pg_data
Redis 7Container Redis com AOF em volume redis_data
Object storageVolume local (/opt/hypergestor/uploads) ou bucket
RegistryArtifact Registry no mesmo projeto GCP (pull de images
customizadas se/quando precisar — build é feito na VM)

Autenticação e cookies de sessão

Toda API usa o authPlugin de @hg/core, que valida o cookie opaco hg_session contra Redis. O cookie é emitido pelo user-api no login.

Configuração em prod/HML

  • httpOnly: true, secure: true, sameSite: 'lax'
  • domain: .onlyfordev.xyz — fluxo entre subdomínios (eTLD+1 comum)

Todos os subdomínios compartilham o mesmo domínio → SameSite=lax funciona (cross-subdomain é same-site). Iframes editor/media também passam cookies.

CORS

Cada API lê CORS_ORIGINS (env do docker-compose). Setar no docker/.env com as 5 SPAs:

CORS_ORIGINS=https://cms.onlyfordev.xyz,https://hub.onlyfordev.xyz,https://admin.onlyfordev.xyz,https://editor.onlyfordev.xyz,https://media.onlyfordev.xyz

SSE (/events no hub-api)

Nginx faz proxy com proxy_buffering off e proxy_read_timeout 24h pra suportar long-lived SSE.

Fase HML

  • Região: us-central1
  • VM: e2-medium (2 vCPU shared / 4GB RAM) — ~R$125/mês
  • Disco: 30GB PD-balanced — ~R$10/mês
  • Crédito autopop360: R$1785 ativos cobrem ~13 meses

Decisões

  • Single VM em vez de Cloud Run — evita org policy + sem limite de backend buckets
  • Postgres containerizado em vez de Cloud SQL — sem HA/backups managed (trocar por dumps periódicos)
  • Redis AOF no volume local — sobrevive restart, não sobrevive destroy
  • Let's Encrypt wildcard via webroot — certbot companion renova a cada 12h
  • Deletion protection off em HML — pra iterar rápido

Fase Produção — a definir

Mesma topologia como ponto de partida (single-VM e2-standard-2) com:

  • deletion_protection = true na VM
  • Disco maior (50-100GB)
  • Backups do Postgres via cron rodando pg_dump pra GCS
  • Domínio real (não descartável)
  • Migrar pra Cloud SQL/Memorystore quando o uso pedir (PR dedicada)

Pipelines de deploy

Subida inicial (HML)

# 1. Provisionar infra
cd infra/environments/hml
terraform init
terraform apply

# 2. Delegar DNS no Namecheap → NS do Cloud DNS (terraform output)

# 3. Rodar migrations + seed
pnpm deploy:migrate --seed

# 4. Acessar https://admin.onlyfordev.xyz

Deploy recorrente

# Push no código → deploy na VM
pnpm deploy:vm [branch]

# Só migrations
pnpm deploy:migrate

Os scripts SSH pra VM, fazem git pull, rebuildam SPAs e reciclaram os containers.

Rollback

ssh joao@<VM_IP>
cd /opt/hypergestor
git checkout <commit-anterior>
cd docker && docker compose up -d --build