docs: runbook de operação (Traefik + Convex self-hosted) e link no README
This commit is contained in:
parent
bb0a47099f
commit
70d91b77c9
2 changed files with 206 additions and 0 deletions
|
|
@ -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 self‑hosted)
|
||||||
|
- 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
202
docs/OPERACAO-PRODUCAO.md
Normal file
|
|
@ -0,0 +1,202 @@
|
||||||
|
# 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_EMAIL` precisa 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ç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 sanity‑check)
|
||||||
|
|
||||||
|
## Convex self‑hosted — 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 self‑hosted)
|
||||||
|
1. Registrar runner na VPS:
|
||||||
|
- Repo → Settings → Actions → Runners → New self‑hosted → 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 self‑hosted: imagem oficial `ghcr.io/get-convex/convex-backend`
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue