# 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.