← Volver al blog
Conceptos #multi-tenant

Apps multi-tenant y bases de datos por app

Un servidor, muchas apps aisladas. Cómo StreamHub usa apps, tenants, SQLite por app y prefijos de sala para mantener clientes y cargas de trabajo limpiamente separados.

2 min de lectura
Read in English

Las apps son la unidad de aislamiento

En StreamHub, una app es un espacio de streaming autocontenido: live, webinars, camaras-seguridad. Cada app tiene su propia configuración, su propio bucket S3, sus propios tokens de API y — clave — su propio archivo de base de datos. Nada de los streams, grabaciones o credenciales de una app se filtra a otra.

Esto es lo que hace a StreamHub multi-tenant. Podés correr un solo servidor para varios clientes, o para varios departamentos de una misma empresa, sin que jamás vean los datos del otro.

La división global / por app

El estado se divide deliberadamente en dos capas:

  • Una base global (data/streamhub.db) guarda solo registros transversales: tenants, usuarios, tokens de API, el registro de nodos y un puntero a cada app.
  • Una base por app (apps/<app>/app.db) posee todo lo del ámbito de la app: las tablas streams, vods e ingress_auth.

La división corre automática e idempotentemente al arrancar, tras un backup seguro con VACUUM INTO. La consecuencia: borrar una app es local, respaldar una app es un solo archivo, y una carga descontrolada en una app no puede inflar las tablas de otra.

Los prefijos de sala lo unen todo

Cada app declara un livekitRoomPrefix. Cuando un webhook de LiveKit dispara para una sala, StreamHub la mapea de vuelta a la app dueña por el prefijo coincidente más largo. Así un mismo SFU compartido sirve muchas apps aisladas: el espacio de nombres de salas se particiona por app.

Tenants y cuotas

Por encima de las apps están los tenants — el límite de facturación/propiedad. Un tenant posee apps, usuarios y cuotas (máximo de streams concurrentes, minutos de grabación mensuales, almacenamiento). Las cuotas se aplican por tenant y se exponen como gauges de Prometheus, así ves el uso contra los límites de un vistazo.

Crear una app

Todo es una llamada a la API. Crear una app es un solo POST:

curl -X POST $BASE/apps -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"name":"webinars","displayName":"Webinars de la Empresa"}'

Desde ahí adjuntás credenciales S3, generás tokens por app, configurás la URL de callback e instalás plugins — todo acotado a esa única app.

Por qué importa

El aislamiento por app no es solo prolijidad. Significa que podés ofrecerle a un cliente su propio bucket y credenciales, borrar sus datos de forma limpia al darlo de baja, y razonar sobre el radio de impacto: un webhook mal configurado o un disco lleno golpean una app, no todo el servidor.