You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

122 lines
6.5 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# Plan mínimo de CI/CD, healthcheck y backups (pendiente de decisiones)
Este documento describe un plan pragmático y de bajo mantenimiento para asegurar despliegues seguros y copias de seguridad consistentes, sin introducir infra innecesaria. No aplicar todavía: sirve como guía de implementación para la siguiente iteración.
## Contexto actual (resumen)
- Despliegue: push a main en Forgejo → webhook a CapRover → build/deploy con Dockerfile.
- Imagen: basada en oven/bun con utilidades de depuración (curl, netcat, sqlite3). Útil para inspección.
- Healthcheck en Dockerfile “permisivo”: permite éxito aunque /health falle (usa `|| exit 0`).
- Script de arranque con `sleep 10` (resto histórico).
- No hay guardarraíl que bloquee despliegue si fallan tests.
## Objetivos
1) Evitar desplegar una versión rota a producción (guardarraíl mínimo).
2) Mejorar detección temprana de fallos (healthcheck real).
3) Asegurar backups diarios consistentes sin parar el servicio y con verificación de integridad.
4) Mantener la simplicidad operativa.
## Decisiones pendientes (elegir antes de implementar)
- [ ] Disparo de despliegue (elige 1):
- [ ] A) Desplegar solo con tags (vX.Y.Z). Flujo: tests locales → tag → push → CapRover deploy.
- [ ] B) Hook server-side en Forgejo (pre-receive/update) que corre `bun test` y rechaza el push si falla.
- [ ] C) “Webhook gate” mínimo: un endpoint propio que ejecuta tests y reenvía a CapRover solo si pasan.
- [ ] Herramientas en imagen:
- [x] Mantener sqlite3 por ahora (útil en prod).
- [ ] Retirar curl y netcat tras piloto (no crítico).
- [ ] Monitor externo muy ligero:
- [ ] Usar Uptime-Kuma (o similar) para /health cada 1 min.
- [ ] No usar monitor externo (conformarse con CapRover).
- [ ] Almacenamiento de backups:
- [ ] Mismo disco (operacional; conservar varias generaciones).
- [ ] Segundo disco/NAS/otro servidor (preferible si posible).
- [ ] “Smoke” post-deploy:
- [ ] Enviar DM a BOT_OWNER (si configurado) de “deploy OK”.
- [ ] Solo registrar métrica (`app_started_at` y `migrations_ok`).
## Cambios planificados (sin aplicar todavía)
### 1) Arranque y healthcheck
- startup.sh: eliminar `sleep 10` y arrancar directamente `bun run index.ts`.
- Dockerfile: endurecer HEALTHCHECK para que falle si /health no responde 200 (eliminar `|| exit 0`). Mantener endpoint básico (sin `full=1`).
- EXPOSE: mantener lectura de PORT por env; sin cambios funcionales.
### 2) Guardarraíl de despliegue (elige 1 opción)
- Opción A — Deploy por tags:
- Convención de versiones semánticas (vX.Y.Z).
- Procedimiento: correr `bun test` local → crear tag → push tag → CapRover deploy.
- Pros: cero infra extra; fácil de revertir en hábitos.
- Opción B — Hook server-side en Forgejo:
- Añadir hook `pre-receive` (o `update`) que:
- Chequea que el push es a `refs/heads/main`.
- Ejecuta `bun test` en un checkout temporal del commit/refs recibido.
- Si falla, exit ≠ 0 y Forgejo rechaza el push.
- Pros: no requiere runners ni servicios; bloquea pushes rotos.
- Opción C — Webhook gate mínimo:
- Service pequeño (script) que recibe el webhook de Forgejo, ejecuta `bun test` y solo si pasa reenvía el webhook a CapRover.
- Pros: aísla validación del despliegue; Contras: un servicio más que mantener.
### 3) Imagen Docker
- Mantener sqlite3 para inspección en producción.
- Plan (postpiloto): retirar curl/netcat si no se usan.
- Añadir `.dockerignore` para reducir contexto (node_modules, tests si no son necesarios en build, etc.) — opcional a corto plazo.
### 4) Backups de SQLite (prioridad alta)
- Método recomendado: backup “online” con sqlite3 (sin detener el servicio).
- Procedimiento diario (cron en host o contenedor programador):
1) Ruta base: `/app/data/tasks.db`.
2) Crear directorio de backups: `/app/data/backups/`.
3) Generar nombre con timestamp: `tasks-YYYYMMDD-HHmm.sqlite3`.
4) Ejecutar backup online:
- `sqlite3 /app/data/tasks.db ".backup '/app/data/backups/tasks-YYYYMMDD-HHmm.sqlite3'"`.
- Alternativa: `VACUUM INTO` a un archivo temporal y luego renombrar.
5) Verificar integridad en la copia:
- `sqlite3 /app/data/backups/tasks-... "PRAGMA integrity_check;"` debe devolver `ok`.
- Registrar resultado en un log de backups (`/app/data/backups/backup.log`).
6) Comprimir (opcional): `gzip -9`.
7) Retención: mantener p. ej. 7 diarias + 4 semanales; purgar el resto.
- Notas:
- Con WAL activado, `.backup` maneja consistencia; evita copiar a pelo sin incluir `-wal/-shm`.
- Si se dispone de otro disco/servidor, replicar las copias (scp/rsync) al menos semanalmente.
- Ensayo mensual de restauración:
- En un contenedor aislado: montar una copia del backup como `tasks.db` y arrancar la app; comprobar `/health` y que migraciones aplican.
### 5) Detección temprana de fallos
- Healthcheck real (Dockerfile): CapRover marcará “unhealthy” si /health no está OK.
- Smoke postdeploy:
- Si se elige DM: encolar un mensaje “deploy OK” a BOT_OWNER tras el arranque (idempotente).
- Alternativa sin DM: exponer métricas `app_started_at` (epoch ms) y `migrations_ok` (0/1).
### 6) Runbook operativo (resumen)
- Desplegar:
- Opción A (tags): `bun test` local → `git tag vX.Y.Z``git push --tags`.
- Opción B/C: `git push` a main (tests bloquean si fallan).
- Verificación:
- CapRover: health verde.
- `/health` OK; `/metrics` visible.
- Logs sin errores de migraciones/cola.
- Rollback:
- CapRover: revertir a la versión previa (history).
- Backup manual (ad hoc):
- Ejecutar el mismo comando `.backup` y verificar integridad.
- Restore:
- Parar app (si procede), sustituir `data/tasks.db` por la copia, arrancar, verificar `/health`.
## Checklist de implementación
- [ ] Decidir estrategia de trigger de despliegue (A/B/C).
- [ ] Endurecer HEALTHCHECK en Dockerfile (sin `|| exit 0`).
- [ ] Eliminar `sleep` en startup.sh.
- [ ] (Opcional) Añadir `.dockerignore`.
- [ ] Implementar guardarraíl elegido:
- [ ] A) Convención de tags y documentación de flujo.
- [ ] B) Hook en Forgejo con `bun test`.
- [ ] C) Webhook gate que ejecuta tests y reenvía a CapRover.
- [ ] Programar backup diario con verificación de integridad y retención.
- [ ] Documentar y ensayar restore.
- [ ] (Opcional) Monitor externo para `/health`.
- [ ] (Opcional) Smoke postdeploy (DM o métricas).
## Impacto esperado
- Riesgo de “romper prod” se reduce significativamente con coste operativo mínimo.
- Backups confiables y verificables sin actividad manual diaria.
- Cambios reversibles y sin bloqueo del desarrollo.