From 70d91b77c9424ea5bdcf7587d2194ca0e9f5954e Mon Sep 17 00:00:00 2001 From: Esdras Renan Date: Wed, 8 Oct 2025 11:41:03 -0300 Subject: [PATCH] =?UTF-8?q?docs:=20runbook=20de=20opera=C3=A7=C3=A3o=20(Tr?= =?UTF-8?q?aefik=20+=20Convex=20self-hosted)=20e=20link=20no=20README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 + docs/OPERACAO-PRODUCAO.md | 202 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 206 insertions(+) create mode 100644 docs/OPERACAO-PRODUCAO.md diff --git a/README.md b/README.md index c3c0667..f590649 100644 --- a/README.md +++ b/README.md @@ -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. +### 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 - Exemplo na raiz: `.env.example` — copie para `.env` e preencha segredos. diff --git a/docs/OPERACAO-PRODUCAO.md b/docs/OPERACAO-PRODUCAO.md new file mode 100644 index 0000000..d5f8074 --- /dev/null +++ b/docs/OPERACAO-PRODUCAO.md @@ -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= +DATABASE_URL=file:./prisma/db.sqlite + +# SMTP +SMTP_ADDRESS= +SMTP_PORT=465 +SMTP_DOMAIN= +SMTP_USERNAME= +SMTP_PASSWORD= +SMTP_AUTHENTICATION=login +SMTP_ENABLE_STARTTLS_AUTO=false +SMTP_TLS=true +MAILER_SENDER_EMAIL="Nome " + +# Máquina/inventário +MACHINE_PROVISIONING_SECRET= +MACHINE_TOKEN_TTL_MS=2592000000 +FLEET_SYNC_SECRET= + +# 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 ` +- 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` +