6.3 KiB
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
maine 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_webmonta 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)
- Gerar build em
/home/renan/apps/sistema.build.<stamp-ou-sha>(CI faz isso). - Atualizar symlink:
ln -sfn /home/renan/apps/sistema.build.<novo> /home/renan/apps/sistema.current. - Rollout do serviço web:
docker service update --force sistema_web. - Opcional: se o
stack.ymlmudou, 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","corepack enable && corepack prepare pnpm@10.20.0 --activate && pnpm exec prisma migrate deploy && pnpm start -p 3000"]- Se você optar por usar
/app/scripts/start-web.sh(como no workflow atual), ele já garantepnpm@10.20.0via Corepack/NPM antes de rodar Prisma/Next. Certifique-se de copiar esse arquivo para o build publicado; sem ele, a task cai compnpm: command not found.
- Env obrigatórias (URLs válidas):
DATABASE_URL=file:/app/data/db.sqliteNEXT_PUBLIC_CONVEX_URL=http://sistema_convex_backend:3210NEXT_PUBLIC_APP_URL=https://tickets.esdrasrenan.com.brBETTER_AUTH_URL=https://tickets.esdrasrenan.com.br
- Update com
stop-first(evitadatabase is lockedem SQLite) + healthcheck.
Prisma/SQLite do stack
- O volume do stack é namespaced:
sistema_sistema_db(nãosistema_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 \
node:20-bullseye bash -lc 'corepack enable; corepack prepare pnpm@10.20.0 --activate; pnpm i --no-frozen-lockfile; pnpm exec 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:
-
Serviço ainda montava build antigo e comando antigo (spec não mudava).
- Inspect mostrava
Source=/home/renan/apps/sistema.build.<antigo> -> /appe comando inline antigo. - Correção: redeploy do stack com mount em
/home/renan/apps/sistema.current+docker service update --force sistema_web.
- Inspect mostrava
-
Migration P3009 ("failed migrations") no SQLite do stack.
- Motivo: resolver/aplicar migrations no volume errado (
sistema_db), enquanto o serviço usasistema_sistema_db. - Correção determinística:
docker service scale sistema_web=0prisma migrate resolve --rolled-back 20251015223259_add_company_provisioning_codeno volumesistema_sistema_db(comando acima em "Prisma/SQLite do stack").pnpm exec prisma migrate deploydocker service scale sistema_web=1(ouupdate --force).
- Motivo: resolver/aplicar migrations no volume errado (
-
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.
-
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 ....
- Correção: definir URLs válidas no stack ou via
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.currentdocker 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 "corepack enable && corepack prepare pnpm@10.20.0 --activate && pnpm exec prisma migrate deploy && pnpm start -p 3000"' \
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 \
node:20-bullseye bash -lc 'corepack enable; corepack prepare pnpm@10.20.0 --activate; pnpm i --no-frozen-lockfile; pnpm exec prisma migrate resolve --rolled-back 20251015223259_add_company_provisioning_code; pnpm exec 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. Ostack.ymlsó 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 hard‑reload no navegador.