docs: runbook de operação (Traefik + Convex self-hosted) e link no README

This commit is contained in:
Esdras Renan 2025-10-08 11:41:03 -03:00
parent bb0a47099f
commit 70d91b77c9
2 changed files with 206 additions and 0 deletions

View file

@ -42,6 +42,10 @@ Aplicação Next.js 15 com Convex e Better Auth para gestão de tickets da Rever
> Se o CLI perguntar sobre configuração do projeto Convex, escolha criar um novo deployment local (opção padrão) e confirme. As credenciais são armazenadas em `.convex/` automaticamente. > Se o CLI perguntar sobre configuração do projeto Convex, escolha criar um novo deployment local (opção padrão) e confirme. As credenciais são armazenadas em `.convex/` automaticamente.
### Deploy em produção (Traefik + Convex selfhosted)
- Guia completo: consulte `docs/OPERACAO-PRODUCAO.md:1`.
- Stack Swarm: `stack.yml:1` (roteado por Traefik, rede `traefik_public`).
### Variáveis de ambiente ### Variáveis de ambiente
- Exemplo na raiz: `.env.example` — copie para `.env` e preencha segredos. - Exemplo na raiz: `.env.example` — copie para `.env` e preencha segredos.

202
docs/OPERACAO-PRODUCAO.md Normal file
View file

@ -0,0 +1,202 @@
# Runbook de Operação — Produção (Traefik + Convex SelfHosted)
> Documento vivo. Guia completo para (1) preparar a VPS, (2) fazer deploy com Traefik/Swarm, (3) publicar o backend Convex selfhosted, (4) popular seeds e (5) operar/atualizar com ou sem CI/CD. Tudo em PTBR.
## Visão geral
- Frontend (Next.js) público em `tickets.esdrasrenan.com.br`.
- Backend Convex selfhosted 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_EMAIL` precisa de aspas se contiver espaços.
- Em selfhosted, 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 selfhosted (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ço `web` porta 3000.
- `convex.esdrasrenan.com.br` → serviço `convex_backend` porta 3210.
## Deploy da stack
Via Portainer (recomendado)
1. Abra o Portainer → Stacks → Add/Update e cole o conteúdo de `stack.yml` (ou vincule ao repositório para “Pull/Deploy”).
2. 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_web`
- `docker 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 `/version` responde para sanitycheck)
## Convex selfhosted — configuração inicial
1. 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|...
```
2. 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:20` com `pnpm exec convex deploy` (ver seção Convex).
- Reiniciar serviços sem alterar o stack: `docker service update --force sistema_web` (ou `sistema_convex_backend`).
## CI/CD (GitHub Actions + runner selfhosted)
1. Registrar runner na VPS:
- Repo → Settings → Actions → Runners → New selfhosted → Linux
- Labels: `self-hosted, linux, vps`
2. Ajustar job `deploy` em `.github/workflows/ci-cd-web-desktop.yml` para:
- `cd /srv/apps/sistema && git pull`
- `docker stack deploy --with-registry-auth -c stack.yml sistema`
3. Adicionar job `convex_deploy` (opcional) no mesmo runner:
- Executar container `node:20-bullseye` com envs `CONVEX_SELF_HOSTED_URL` e `CONVEX_SELF_HOSTED_ADMIN_KEY` (secrets do GitHub)
- Rodar `pnpm exec convex deploy`
Benefícios
- Push na `main` → pipeline atualiza app e (opcionalmente) publica mudanças no Convex.
## Trocar domínio ou VPS (checklist)
1. Criar DNS para novos domínios (app/convex) apontando para a VPS nova.
2. Copiar o projeto para `/srv/apps/sistema` na nova VPS.
3. Ajustar `.env` com novos domínios e SEGREDOS novos (gire novamente em produção).
4. Deploy da stack.
5. Convex: gerar Admin Key no novo container e `convex deploy` apontando para a nova URL.
6. 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.
- `MAILER_SENDER_EMAIL` com erro de parsing:
- Adicionar aspas no `.env`.
- `pnpm` reclama de workspace:
- `pnpm-workspace.yaml` já aponta só para `.` (evita apps/desktop no deploy).
- Portainer erro de bind relativo:
- Usar caminho absoluto `/srv/apps/sistema:/app` no stack (feito).
- Prisma CLI “not found”:
- Instalar devDependencies no build (`NPM_CONFIG_PRODUCTION=false` e `pnpm install --prod=false`).
- Convex CLI pedindo interação:
- Não usar CLI em produção; usamos imagem oficial `convex-backend` e `convex deploy` via container transitório com Admin Key.
## 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 `.env` com segredos reais.
- Guarde a `Admin Key` do 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 selfhosted: imagem oficial `ghcr.io/get-convex/convex-backend`