ADR-004 — SQLite y filesystem en un único binario servidor¶
- Estado: propuesto.
- Fecha: 2026-09-04.
- Edición documental: v0.3; alcance de comprobación en el índice.
English version: ../../adr/ADR-004-sqlite-single-binary.md
Contexto¶
El usuario objetivo aloja un círculo pequeño en un homelab. La simplicidad de instalar, copiar, actualizar y reparar importa tanto como el rendimiento. Un broker, base externa y object storage obligatorios aumentan puntos de fallo antes de demostrar que son necesarios.
Decisión¶
Usar un proceso Go con SQLite en WAL para membresías, material público, control de acceso y colas. Guardar blobs cifrados inmutables en filesystem local. Empaquetar un binario servidor por plataforma y una imagen opcional con un directorio persistente.
Un realm por instancia, un escritor lógico, transacciones breves y backpressure. La base usa disco local compatible; no NFS/SMB para WAL ni escritura compartida de varias instancias. El proxy TLS y las herramientas de observabilidad son opcionales, no dependencias de datos obligatorias.
La compatibilidad del driver SQLite con build estático, licencias, mantenimiento, parámetros de durabilidad y plataformas debe validarse antes de elegirlo. Un binario distribuible no exige que todo el ecosistema use un solo lenguaje o proceso.
Requisitos verificados de durabilidad¶
Motor: exigir SQLite 3.51.3 o posterior, o un backport documentado del arreglo WAL-reset, como 3.44.6 o 3.50.7. El fallo afecta a determinadas carreras entre escritura y checkpoint. Verificar la versión realmente embebida por el driver y por SQLCipher, no solo el paquete envoltorio. Fuente: SQLite, WAL-reset.
Confirmación: usar journal_mode=WAL y synchronous=FULL en las conexiones que hacen escrituras durables. Con NORMAL, un corte de alimentación puede perder una transacción ya confirmada. Revisar también las opciones de sincronización específicas del sistema operativo; la garantía depende de que almacenamiento y VFS cumplan su contrato. Fuente: SQLite, synchronous.
Estas condiciones son requisitos del diseño para servidor y estado criptográfico local. Un benchmark no puede relajarlas sin cambiar explícitamente la semántica ofrecida al usuario. Las pruebas deben distinguir matar el proceso de perder la alimentación del host.
Alternativas¶
| Alternativa | Ventaja | Motivo para aplazar |
|---|---|---|
| PostgreSQL | Concurrencia de escritura y operación multiinstancia | Añade servicio y backup independiente sin necesidad demostrada |
| Redis/RabbitMQ | Funciones avanzadas de cola | SQLite ofrece durabilidad suficiente como hipótesis inicial |
| S3/MinIO obligatorio | Escala/gestión de objetos | Aumenta dependencias para archivos de un grupo doméstico |
| Base solo en memoria | Simplicidad superficial | Perdería entregas pendientes al reiniciar |
Consecuencias operativas¶
El rendimiento de escritura y disco marca el límite; WAL no ofrece escritores concurrentes ilimitados. El perfil Standalone no promete alta disponibilidad. Se miden latencia de persistencia, locks, fan-out, tamaño de WAL y GC antes de ampliar alcance.
V1 ofrece backup offline del directorio completo tras detener limpiamente. La futura copia online debe coordinar snapshot SQLite, blobs y limpieza. Los blobs se cargan en staging y se confirman con orden de persistencia documentado; un reconciliador elimina huérfanos después de una ventana segura.
El backup del servidor contiene metadatos y secretos operativos y necesita cifrado externo y control de acceso. No sustituye al kit personal ni al archivo de historial. Restaurar no autoriza retroceder el estado criptográfico de los clientes.
Migración con backup y acceso exclusivo; rollback mediante snapshot compatible. La retención, las cuotas y la caducidad se muestran al operador y al cliente. El espacio agotado produce error, nunca una aceptación de entrega no durable.
Decisión de driver (M0.3)¶
El relay usa modernc.org/sqlite (Go puro, binario estático sin cgo). La versión 1.58.0 embebe SQLite 3.53.4, que incluye el arreglo de WAL-reset; el almacén comprueba la versión embebida al abrir y un test falla por debajo de 3.51.3. El core cliente usa rusqlite con SQLite empaquetado y la misma comprobación. La integración de SQLCipher en el cliente es tarea de la fase 2.
Criterios de aceptación¶
Instalar y arrancar sin DB externa; probar corte de proceso, disco lleno, WAL grande, expiración y backup/restore aislado. Medir carga representativa sobre hardware doméstico, sin afirmar rendimiento de Raspberry Pi antes de medirlo. Validar permisos del directorio y actualización entre dos versiones de esquema.
Reabrir cuando métricas demuestren saturación sostenida o se decida estudiar HA. ADR-007 registra esa posibilidad después de V1, sin sustituir esta decisión para Standalone. Elegir PostgreSQL o rqlite requeriría revisar adaptadores, operaciones atómicas y operación; no se garantiza una migración transparente ni se añade un perfil distribuido preventivamente.
Referencias: arquitectura, SQLite WAL, backup. Alcance de revisión: índice.