05 — Deploy e Infraestrutura
Ambientes
| Ambiente | Propósito | Branch | URLs |
|---|---|---|---|
| Local | Dev | — | localhost (app :3001, service :3002, website :3000, backoffice :3003, hasura :8080) |
| Produção | Clientes | master | *.vectorgen.ai |
Backend único: apps/service (NestJS, :3002 / service.vectorgen.ai) atende app e backoffice. Não há um segundo API só para admin — o SPA apps/backoffice chama o mesmo service com client=backoffice e rotas /admin/* (gate por BACKOFFICE_ADMIN_EMAILS). Hasura GraphQL também é compartilhado; permissões diferem por JWT/role.
| UI | Porta local | Domínio prod | API |
|---|---|---|---|
apps/app | :3001 | app.vectorgen.ai | service + Hasura |
apps/backoffice | :3003 | backoffice.vectorgen.ai | mesmo service + Hasura |
apps/website | :3000 | vectorgen.ai | service (planos/health) quando necessário |
apps/service | :3002 | service.vectorgen.ai | — (API REST) |
| Hasura | :8080 | api.vectorgen.ai | — (GraphQL) |
Fonte canônica de domínios: packages/brand/src/config.ts → domains. Uso obrigatório e integração por app: 10-brand-kit.
Produção
- Provider: Digital Ocean
- Orquestração: Dokploy + Docker
- SSH: credenciais em
.envna raiz (SERVER_IP,SSH_USER); scripts carregam viascripts/lib/load-root-env.sh+scripts/lib/ssh-env.sh. Preferir./scripts/prod/server-ssh.shepnpm server:docker— ver.cursor/rules/server-ssh.mdcescripts/README.md
./scripts/prod/server-ssh.sh 'docker ps'
pnpm server:docker -- logs --tail 100 vectorgen-service
Setup one-time: adicionar chave SSH default ao droplet na criação; definir SERVER_IP no .env.
Containers principais
| Container | Função |
|---|---|
vectorgen-postgres | PostgreSQL |
vectorgen-pgbouncer | Connection pooler (porta 6432) |
vectorgen-redis | Redis |
vectorgen-hasura | GraphQL |
vectorgen-service | API |
vectorgen-app | Dashboard |
vectorgen-backoffice | Admin interno |
vectorgen-website | Marketing |
Fonte: cloud/dokploy/apps.json — 8 Applications (postgres, redis, pgbouncer, hasura, service, app, backoffice, website). Sem Compose em produção. Aplicar no painel: pnpm dokploy:validate → pnpm dokploy:sync (ver cloud/dokploy/README.md).
Deploy: push em master → Dokploy rebuild das Applications afetadas (GitHub App webhook).
Ordem completa: postgres → redis → pgbouncer → hasura → service → app → backoffice → website
pnpm dokploy:validate
pnpm dokploy:deploy # requer DOKPLOY_* no .env
pnpm dokploy:health
./cloud/dokploy/deploy-hooks.sh env-templates production
Apps — portas e health checks
Frontend App (apps/app)
- Porta: 3001
- Domínio prod:
app.vectorgen.ai - Build:
pnpm run build - Start:
node server.js - Health:
http://localhost:3001/healthz
Variáveis: VITE_API_URL, VITE_HASURA_GRAPHQL_URL, VITE_LOGO_URL, VITE_APP_NAME, VITE_GOOGLE_CLIENT_ID
Backoffice (apps/backoffice)
- Porta: 3003
- Domínio prod:
backoffice.vectorgen.ai - Build:
pnpm run build - Start:
node server.js - Health:
http://localhost:3003/healthz
Variáveis: VITE_API_URL, VITE_HASURA_GRAPHQL_URL, VITE_LOGO_URL, VITE_APP_NAME, VITE_GOOGLE_CLIENT_ID
Backend Service (apps/service)
- Porta: 3002
- Build:
pnpm run build - Start:
pnpm start - Health:
http://localhost:3002/health
Variáveis: NODE_ENV, PORT, DATABASE_URL, HASURA_GRAPHQL_ENDPOINT, HASURA_ADMIN_SECRET, JWT_SECRET
Website (apps/website)
- Porta: 3000
- Build:
pnpm run build - Start:
node server.js - Health:
http://localhost:3000/healthz
Variáveis: NODE_ENV, PORT, NEXT_PUBLIC_API_URL
Deploy com Docker (local / manual)
docker build -f apps/app/Dockerfile -t vectorgen-app:latest .
docker build -f apps/backoffice/Dockerfile -t vectorgen-backoffice:latest .
docker build -f apps/service/Dockerfile -t vectorgen-service:latest .
docker build -f apps/website/Dockerfile -t vectorgen-website:latest .
Ordem recomendada: service → app → backoffice → website
Deploy produção (Dokploy)
Primeira vez (greenfield): cloud/BOOTSTRAP.md — DO, Dokploy install, GitHub, prompts IA.
Deploy contínuo (infra já no ar):
- Push / merge em
master - Dokploy build + deploy por app (webhook GitHub App; ou
pnpm dokploy:deploy) - Health checks (matriz completa em 07-security-observability):
- hasura:
/healthz - service:
/health - app:
/healthz - backoffice:
/healthz - website:
/healthz
- hasura:
pnpm dokploy:health
DOKPLOY_HEALTH_JSON=1 pnpm dokploy:health
./scripts/prod/server-ssh.sh 'docker ps'
Guia completo: cloud/BOOTSTRAP.md (greenfield) · cloud/README.md · Por serviço: cloud/apps/ · Dokploy: cloud/dokploy/README.md
Variáveis de ambiente
- Nunca commitar
.env .env.examplepor app- Secrets via Dokploy / painel
Verificação pós-deploy
- Health checks respondendo
- Logs sem erros
- URLs acessíveis
- Variáveis configuradas
Troubleshooting
| Problema | Ações |
|---|---|
| Build falha | Dependências, path do Dockerfile, logs do build |
| App não inicia | Env vars, logs, porta |
| Health check falha | Endpoint existe, timeout, processo rodando |
Runbooks
Rollback
<!-- Documentar passos -->Postgres backup
<!-- Frequency, restore -->Incidente service down
docker logs vectorgen-service --tail 100(oupnpm server:docker -- logs --tail 100 vectorgen-service)- Verificar postgres/redis
- Se P0/P1: o alerta WhatsWave "VG · Critical alert" já deve ter notificado o founder — seguir playbook em 07-security-observability § Incident response
Links relacionados
- 07-security-observability (alertas WhatsWave + IR leve)
cloud/dokploy/README.md