8.2 KiB
8.2 KiB
Runbook de Operação — Produção (Traefik + Convex Self‑Hosted)
Documento vivo. Guia completo para (1) preparar a VPS, (2) fazer deploy com Traefik/Swarm, (3) publicar o backend Convex self‑hosted, (4) popular seeds e (5) operar/atualizar com ou sem CI/CD. Tudo em PT‑BR.
Visão geral
- Frontend (Next.js) público em
tickets.esdrasrenan.com.br. - Backend Convex self‑hosted em
convex.esdrasrenan.com.br(imagem oficial Convex). - Traefik no Docker Swarm (rede
traefik_public) roteando por hostname (sem conflito de portas). - Banco Prisma (SQLite) persistente via volume
sistema_db(mapeado em/app/data). - Estado do Convex persistente via volume
convex_data. - Seeds prontos (Better Auth e dados demo Convex).
Requisitos
- VPS com Docker/Swarm e Traefik já em execução na rede externa
traefik_public. - Portainer opcional (para gerenciar a stack “sistema”).
- Domínios apontando para a VPS:
tickets.esdrasrenan.com.br(frontend)convex.esdrasrenan.com.br(Convex backend)
Layout do servidor
- Código do projeto:
/srv/apps/sistema(bind no stack). - Volumes Swarm:
sistema_db→/app/data(SQLite / Prisma)convex_data→/convex/data(Convex backend)
.env (produção)
Arquivo base: .env na raiz do projeto. Exemplo mínimo (substitua domínios/segredos):
NEXT_PUBLIC_APP_URL=https://tickets.esdrasrenan.com.br
BETTER_AUTH_URL=https://tickets.esdrasrenan.com.br
NEXT_PUBLIC_CONVEX_URL=https://convex.esdrasrenan.com.br
BETTER_AUTH_SECRET=<hex forte gerado por `openssl rand -hex 32`>
DATABASE_URL=file:./prisma/db.sqlite
# SMTP
SMTP_ADDRESS=<smtp.host>
SMTP_PORT=465
SMTP_DOMAIN=<seu-dominio>
SMTP_USERNAME=<usuario>
SMTP_PASSWORD=<senha>
SMTP_AUTHENTICATION=login
SMTP_ENABLE_STARTTLS_AUTO=false
SMTP_TLS=true
MAILER_SENDER_EMAIL="Nome <no-reply@seu-dominio.com>"
# Máquina/inventário
MACHINE_PROVISIONING_SECRET=<hex forte>
MACHINE_TOKEN_TTL_MS=2592000000
FLEET_SYNC_SECRET=<hex forte ou igual ao de provisionamento>
# Outros
CONVEX_SYNC_SECRET=dev-sync-secret
ALERTS_LOCAL_HOUR=8
SYNC_TENANT_ID=tenant-atlas
SEED_TENANT_ID=tenant-atlas
# Importante para self-hosted: comentar se existir
# CONVEX_DEPLOYMENT=...
Atenção
MAILER_SENDER_EMAILprecisa de aspas se contiver espaços.- Em self‑hosted, NÃO usar
CONVEX_DEPLOYMENT.
Stack (Docker Swarm + Traefik)
O arquivo do stack está versionado em stack.yml. Ele sobe:
web(Next.js) — builda e roda na porta interna 3000 (roteada pelo Traefik por hostname).convex_backend— imagem oficial do Convex self‑hosted (porta interna 3210, roteada pelo Traefik).
Bind dos volumes (absolutos, compatível com Portainer/Swarm):
/srv/apps/sistema:/app→ código do projeto dentro do container web.- volume
sistema_db→/app/data(SQLite do Prisma). - volume
convex_data→/convex/data(estado do Convex backend).
Rótulos Traefik (labels) no stack mapeiam:
tickets.esdrasrenan.com.br→ serviçowebporta 3000.convex.esdrasrenan.com.br→ serviçoconvex_backendporta 3210.
Deploy da stack
Via Portainer (recomendado)
- Abra o Portainer → Stacks → Add/Update e cole o conteúdo de
stack.yml(ou vincule ao repositório para “Pull/Deploy”). - Clique em “Deploy the stack” (ou “Update the stack”).
Via CLI
docker stack deploy --with-registry-auth -c /srv/apps/sistema/stack.yml sistema
Verificação
- Serviços:
docker stack services sistema - Logs:
docker service logs -f sistema_webdocker service logs -f sistema_convex_backend
Acesso
- App:
https://tickets.esdrasrenan.com.br - Convex:
https://convex.esdrasrenan.com.br(o importante é o WebSocket do cliente conectar; o path/versionresponde para sanity‑check)
Convex self‑hosted — configuração inicial
- Gerar Admin Key (uma vez, dentro do container do Convex):
# Console/exec no container sistema_convex_backend
./generate_admin_key.sh
# Copiar/guardar a chave: convex-self-hosted|...
- Publicar o código Convex (deploy das functions) — sem instalar nada na VPS:
docker run --rm -it \
-v /srv/apps/sistema:/app \
-w /app \
-e CONVEX_SELF_HOSTED_URL=https://convex.esdrasrenan.com.br \
-e CONVEX_SELF_HOSTED_ADMIN_KEY='COLE_A_CHAVE_AQUI' \
node:20-bullseye bash -lc "corepack enable && corepack prepare pnpm@9 --activate && pnpm install --frozen-lockfile --prod=false && pnpm exec convex deploy"
Observação
- Sempre que alterar código em
convex/, repita o comando acima para publicar as mudanças.
Seeds
- Dados de demonstração Convex: acesse uma vez
https://tickets.esdrasrenan.com.br/dev/seed. - Usuários (Better Auth):
CONTAINER=$(docker ps --format '{{.ID}} {{.Names}}' | grep sistema_web | awk '{print $1}' | head -n1)
docker exec -it "$CONTAINER" bash -lc 'cd /app && pnpm auth:seed'
- Apenas um admin (em produção):
CONTAINER=$(docker ps --format '{{.ID}} {{.Names}}' | grep sistema_web | awk '{print $1}' | head -n1)
docker exec -it "$CONTAINER" bash -lc 'cd /app && \
SEED_USER_EMAIL="seu-email@dominio.com" \
SEED_USER_PASSWORD="suaSenhaForte" \
SEED_USER_NAME="Seu Nome" \
SEED_USER_ROLE="admin" \
pnpm auth:seed'
- Filas padrão:
docker exec -it "$CONTAINER" bash -lc 'cd /app && pnpm queues:ensure'
Atualizações (sem CI)
- App (Next.js):
cd /srv/apps/sistema
git pull
docker stack deploy --with-registry-auth -c stack.yml sistema
- Convex (functions): repetir o container
node:20compnpm exec convex deploy(ver seção Convex). - Reiniciar serviços sem alterar o stack:
docker service update --force sistema_web(ousistema_convex_backend).
CI/CD (GitHub Actions + runner self‑hosted)
- Registrar runner na VPS:
- Repo → Settings → Actions → Runners → New self‑hosted → Linux
- Labels:
self-hosted, linux, vps
- Ajustar job
deployem.github/workflows/ci-cd-web-desktop.ymlpara:cd /srv/apps/sistema && git pulldocker stack deploy --with-registry-auth -c stack.yml sistema
- Adicionar job
convex_deploy(opcional) no mesmo runner:- Executar container
node:20-bullseyecom envsCONVEX_SELF_HOSTED_URLeCONVEX_SELF_HOSTED_ADMIN_KEY(secrets do GitHub) - Rodar
pnpm exec convex deploy
- Executar container
Benefícios
- Push na
main→ pipeline atualiza app e (opcionalmente) publica mudanças no Convex.
Trocar domínio ou VPS (checklist)
- Criar DNS para novos domínios (app/convex) apontando para a VPS nova.
- Copiar o projeto para
/srv/apps/sistemana nova VPS. - Ajustar
.envcom novos domínios e SEGREDOS novos (gire novamente em produção). - Deploy da stack.
- Convex: gerar Admin Key no novo container e
convex deployapontando para a nova URL. - Testar front + WS (sem erro 1006) e seeds conforme necessário.
Problemas comuns e correções
- WebSocket 1006 no front:
- Convex não está recebendo/concluindo handshake WS → ver logs
sistema_convex_backend. - DNS/Traefik incorretos → confirmar labels/hostnames e DNS.
- Convex não está recebendo/concluindo handshake WS → ver logs
MAILER_SENDER_EMAILcom erro de parsing:- Adicionar aspas no
.env.
- Adicionar aspas no
pnpmreclama de workspace:pnpm-workspace.yamljá aponta só para.(evita apps/desktop no deploy).
- Portainer erro de bind relativo:
- Usar caminho absoluto
/srv/apps/sistema:/appno stack (feito).
- Usar caminho absoluto
- Prisma CLI “not found”:
- Instalar devDependencies no build (
NPM_CONFIG_PRODUCTION=falseepnpm install --prod=false).
- Instalar devDependencies no build (
- Convex CLI pedindo interação:
- Não usar CLI em produção; usamos imagem oficial
convex-backendeconvex deployvia container transitório com Admin Key.
- Não usar CLI em produção; usamos imagem oficial
Comandos úteis
- Serviços:
docker stack services sistema - Logs:
docker service logs -f sistema_web/docker service logs -f sistema_convex_backend - Reiniciar:
docker service update --force <service> - Status Traefik (se exposto):
docker service logs -f traefik
Segurança
- Nunca commit
.envcom segredos reais. - Guarde a
Admin Keydo Convex em local seguro; use secrets no GitHub. - Gire segredos ao migrar de VPS/domínio.
Referências
- Stack do projeto:
stack.yml - CI/CD (web + desktop):
.github/workflows/ci-cd-web-desktop.yml - Guia CI/CD Desktop:
apps/desktop/docs/guia-ci-cd-web-desktop.md - Docs Convex self‑hosted: imagem oficial
ghcr.io/get-convex/convex-backend