sistema-de-chamados/docs/archive/deploy-runbook.md
2025-11-05 20:49:19 -03:00

6.1 KiB
Raw Permalink Blame History

Deploy runbook (Swarm) — Arquivo

Nota: este runbook foi arquivado. Utilize docs/operations.md para o fluxo atualizado de deploy.

Este guia documenta o fluxo de deploy atual e os principais passos de diagnóstico/correção que resolveram o problema do front não atualizar mesmo com o CI verde.

Visão geral (como você trabalha)

  • Você dá push na main e aguarda o GitHub Actions concluir.
  • O pipeline cria um build imutável no servidor em /home/renan/apps/sistema.build.<release>.
  • Um symlink estável aponta para o release ativo: /home/renan/apps/sistema.current.
  • O serviço sistema_web monta sempre /home/renan/apps/sistema.current:/app. Para atualizar, basta mudar o symlink e forçar a task.

Resultado: front/back sobem com o novo código sem editar o stack a cada release.

Fluxo de release (mínimo)

  1. Gerar build em /home/renan/apps/sistema.build.<stamp-ou-sha> (CI faz isso).
  2. Atualizar symlink: ln -sfn /home/renan/apps/sistema.build.<novo> /home/renan/apps/sistema.current.
  3. Rollout do serviço web: docker service update --force sistema_web.
  4. Opcional: se o stack.yml mudou, aplicar: docker stack deploy --with-registry-auth -c /home/renan/apps/sistema.build.<novo>/stack.yml sistema.

Stack estável (essência)

  • Mount fixo: /home/renan/apps/sistema.current:/app (não interpolar APP_DIR).
  • Comando inline (sem script), com migrations na subida:
    • command: ["bash","-lc","bun install --frozen-lockfile && bun x prisma migrate deploy && bun run start:bun"]
    • Se você optar por usar /app/scripts/start-web.sh (como no workflow atual), garanta que o script execute bun install antes de rodar Prisma/Next. Certifique-se de copiar esse arquivo para o build publicado; sem ele, a task cai com bun: command not found.
  • Env obrigatórias (URLs válidas):
    • DATABASE_URL=file:/app/data/db.sqlite
    • NEXT_PUBLIC_CONVEX_URL=http://sistema_convex_backend:3210
    • NEXT_PUBLIC_APP_URL=https://tickets.esdrasrenan.com.br
    • BETTER_AUTH_URL=https://tickets.esdrasrenan.com.br
  • Update com stop-first (evita database is locked em SQLite) + healthcheck.

Prisma/SQLite do stack

  • O volume do stack é namespaced: sistema_sistema_db (não sistema_db).
  • Ao operar Prisma fora do Swarm, use SEMPRE este volume e a mesma DATABASE_URL:
APP_DIR=/home/renan/apps/sistema.current
docker run --rm -it \
  -e DATABASE_URL=file:/app/data/db.sqlite \
  -v "$APP_DIR:/app" -v sistema_sistema_db:/app/data -w /app \
  oven/bun:1 bash -lc "bun install --frozen-lockfile && bun x prisma migrate status"

Diagnóstico rápido

  • Ver a task atual + erros: docker service ps --no-trunc sistema_web
  • Logs frescos do serviço: docker service logs --since=2m -f sistema_web
  • Spec aplicado (Args + Mounts):
docker service inspect sistema_web \
  --format '{{json .Spec.TaskTemplate.ContainerSpec.Args}} {{json .Spec.TaskTemplate.ContainerSpec.Mounts}}'
  • Envs do serviço: docker service inspect sistema_web --format '{{json .Spec.TaskTemplate.ContainerSpec.Env}}'

O incidente (front não atualizava) — causa e correções

Sintomas:

  • Actions verde, mas UI antiga; logs com rollbacks de docker service update.

Causas encontradas:

  1. Serviço ainda montava build antigo e comando antigo (spec não mudava).

    • Inspect mostrava Source=/home/renan/apps/sistema.build.<antigo> -> /app e comando inline antigo.
    • Correção: redeploy do stack com mount em /home/renan/apps/sistema.current + docker service update --force sistema_web.
  2. Migration P3009 ("failed migrations") no SQLite do stack.

    • Motivo: resolver/aplicar migrations no volume errado (sistema_db), enquanto o serviço usa sistema_sistema_db.
    • Correção determinística:
      • docker service scale sistema_web=0
      • prisma migrate resolve --rolled-back 20251015223259_add_company_provisioning_code no volume sistema_sistema_db (comando acima em "Prisma/SQLite do stack").
      • bun x prisma migrate deploy
      • docker service scale sistema_web=1 (ou update --force).
  3. Rollback por script ausente (/app/scripts/start-web.sh).

    • Task caía com exit 127 porque o build não continha o script.
    • Correção: voltar ao comando inline no stack (sem depender do script) OU garantir o script no build e executável.
  4. Falha de env (Invalid URL em NEXT_PUBLIC_APP_URL/BETTER_AUTH_URL).

    • Correção: definir URLs válidas no stack ou via docker service update --env-add ....

Cheatsheet de correções

  • Forçar rollout da task:

    • docker service update --force sistema_web
  • Aplicar build novo (sem tocar stack):

    • ln -sfn /home/renan/apps/sistema.build.<novo> /home/renan/apps/sistema.current
    • docker service update --force sistema_web
  • Corrigir mount/args no serviço (hotfix):

docker service update \
  --mount-rm target=/app \
  --mount-add type=bind,src=/home/renan/apps/sistema.current,dst=/app \
  --args 'bash -lc "bun install --frozen-lockfile && bun x prisma migrate deploy && bun run start:bun"' \
  sistema_web
  • Resolver P3009 (volume certo) e aplicar migrations:
APP_DIR=/home/renan/apps/sistema.current
docker service scale sistema_web=0
docker run --rm -it -e DATABASE_URL=file:/app/data/db.sqlite \
  -v "$APP_DIR:/app" -v sistema_sistema_db:/app/data -w /app \
  oven/bun:1 bash -lc "bun install --frozen-lockfile && bun x prisma migrate resolve --rolled-back 20251015223259_add_company_provisioning_code && bun x prisma migrate deploy"
docker service scale sistema_web=1
  • Criar DB se faltar (P1003):

    • docker run --rm -v sistema_sistema_db:/data busybox sh -lc ': >/data/db.sqlite'
  • Ajustar envs em runtime:

    • docker service update --env-add NEXT_PUBLIC_APP_URL=https://tickets.esdrasrenan.com.br --env-add BETTER_AUTH_URL=https://tickets.esdrasrenan.com.br sistema_web

Notas finais

  • Como o stack monta /home/renan/apps/sistema.current, um novo release exige apenas atualizar o symlink e forçar a task. O stack.yml só precisa ser redeployado quando você altera labels/envs/serviços.
  • Se a UI parecer não mudar, valide o mount/args via inspect, confira logs da task atual e force hardreload no navegador.