Operação e deploy
Como o sistema roda no Coolify (web, Horizon e scheduler), as rotinas agendadas, observabilidade, backup e o checklist de go-live.
Deploy no Coolify
O deploy usa o build pack Docker Compose do Coolify, com o
docker-compose.prod.yaml e o Dockerfile da raiz. Uma imagem, três
processos: o que muda é o comando.
- app: FrankenPHP servindo HTTP na porta 80; o Traefik termina o TLS.
Health check em
/up. - horizon: processa as filas (e-mails, PDFs de contrato, envio a provedores).
- scheduler: roda as rotinas agendadas.
Separar Horizon e scheduler do web é obrigatório: se o web cair, a régua de cobrança e a emissão de contratos continuam.
A imagem é multi-stage: o estágio build precisa de PHP e Node, porque o
Vite chama php artisan wayfinder:generate durante o pnpm build. O runtime
leva só o necessário, sem Node nem Composer.
Homologação × produção
O compose atual é de homologação (APP_ENV=staging, Postgres e Redis
dentro do compose, INSTALAR_DEV=1 para o demo:popular). Em produção, use
banco e Redis gerenciados com backup externo e deixe INSTALAR_DEV em 0.
Variáveis principais
| Variável | Observação |
|---|---|
APP_KEY | Obrigatória; definida no Coolify. |
APP_URL | https://${SERVICE_FQDN_APP}: o esquema precisa ser explícito, senão quebram links de e-mail, URLs assinadas e o WorkOS. |
APP_TIMEZONE | Fuso do app e da sessão do Postgres (current_date, now()). Padrão America/Sao_Paulo. |
APP_SCHEDULE_TIMEZONE | Fuso das rotinas agendadas. Padrão America/Sao_Paulo. |
WORKOS_CLIENT_ID, WORKOS_API_KEY, WORKOS_REDIRECT_URL | Autenticação. |
DB_*, REDIS_* | Banco e Redis. |
FILESYSTEM_DISK | s3 em produção: comprovantes e contratos nunca em disco público. |
SENTRY_LARAVEL_DSN, SENTRY_TRACES_SAMPLE_RATE | Observabilidade. |
RUN_MIGRATIONS, RUN_STORAGE_LINK | Executados pelo entrypoint no start. |
Rotinas agendadas
Definidas em routes/console.php, no horário de Brasília; exigem o processo
scheduler.
Fuso de Brasília em todo o app
Desde a migration 2026_10_14_000026, o app e a sessão do banco usam
America/Sao_Paulo, e os timestamp já gravados foram convertidos de UTC
(considerando o horário de verão antigo). A migration é reversível. Antes
dela, entre 21h e meia-noite o sistema já "vivia" o dia seguinte. Em consultas
SQL diretas, os horários estão em Brasília.
| Horário | Rotina |
|---|---|
| 05:30 | contratos:emitir-pendentes: emite contrato de reservas confirmadas sem contrato (ignora reservas importadas e viagens passadas) |
| 06:00 | MarcarParcelasAtrasadas e MarcarCreditosExpirados |
| 08:00 | ReguaCobranca: lembrete D-3 e cobrança de atraso a cada 3 dias |
| a cada 5 min | horizon:snapshot |
Observabilidade
- Sentry: ativa ao definir
SENTRY_LARAVEL_DSN. - Horizon:
/horizon, só para administradores. - Logs estruturados: eventos nomeados como
financeiro.regua.*,webhook.*,identidade.acesso_equipe.*, filtráveis por chave.
Backup e restore
- PostgreSQL com backup contínuo e PITR, WAL retido por pelo menos 14 dias.
- Teste de restore antes do go-live e a cada trimestre: restaurar numa
instância descartável, conferir
migrate:status, contar reservas e bater a soma das parcelas com o último relatório de conciliação. - Storage privado em S3 com versionamento.
Go-live
- Janela de virada na baixa temporada.
- Legado em somente leitura (REVOKE de escrita no MySQL) e dump final.
- Rodada de importação no banco de produção;
migrar:conciliarprecisa passar. - Legado em somente leitura por 6 meses.
- DNS e monitoramento reforçado na primeira semana.