|
|
|
|
@ -0,0 +1,121 @@
|
|
|
|
|
# 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 (post‑piloto): 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 post‑deploy:
|
|
|
|
|
- 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 post‑deploy (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.
|