Lightdash

Herramienta de BI en producción sobre trivasa_dw, publicada en dash.frento.com.mx. Reemplaza en la práctica al scaffolding sin adoptar que describe Stack de BI explorado, no adoptado — este deployment vive en una ubicación distinta (trivasa-bi-dev/lightdash/ y trivasa-bi-dev/dbt/, no stack/lightdash/ ni stack/trivasa_dbt/) y sí está conectado a datos reales. Contexto completo de por qué se construyó y qué contiene en Dashboards demo con Lightdash; esta página es la referencia operativa del servicio en sí.

Arquitectura

Cuatro contenedores propios en trivasa-bi-dev/lightdash/docker-compose.yml, separados del resto de la infra Docker de ctunlinux:

ContenedorImagenRol
lightdashlightdash/lightdash:latest (14.1GB — ver nota abajo)App Node, puerto 127.0.0.1:8090
lightdash-dbpgvector/pgvector:pg15Metadata propia de Lightdash (usuarios, proyectos, dashboards) — no es trivasa_dw
lightdash-miniominio/minio:latestStorage S3-compatible para resultados/exports/scheduled deliveries
lightdash-headless-browserghcr.io/browserless/chromium:v2.49.0 (3.84GB)Renderiza dashboards a PNG/PDF para scheduled deliveries en formato imagen. Agregado el 2026-08-09 — no estaba en el despliegue inicial, ver Dashboard como imagen en la red local.

lightdash-minio-init (minio/mc:latest) es un contenedor extra de un solo uso (restart: "no") que crea el bucket al primer arranque y queda Exited (0) permanentemente — no reiniciar ni confundir con un fallo.

La imagen lightdash/lightdash:latest pesa 14.1GB porque trae 9 versiones de dbt instaladas en paralelo (dbt1.4 a dbt1.12, cada una ~700MB–1.1GB, con adaptadores para Postgres/Snowflake/BigQuery/etc.) para soportar conexiones donde el propio servidor compila el proyecto dbt (integración GitHub/GitLab). Este deployment usa el flujo CLI (ver abajo) — nunca ejecuta el dbt embebido — así que ese peso es puro costo de disco, sin impacto en RAM/uso real. No existe tag oficial más liviano; recortarlo de verdad requiere compilar la imagen desde el código fuente de Lightdash, descartado por el riesgo de RAM/disco en este host (ver cierre de despliegue).

Red: por qué está conectado a postgres-warehouse_default

lightdash consulta trivasa_dw directamente por red Docker interna (no por el puerto publicado 5433), resolviendo el host postgres-dw por nombre de contenedor. Por default, docker compose solo conecta un servicio a la red propia del proyecto (lightdash_default), que no tiene visibilidad de la red postgres-warehouse_default donde vive postgres-dw. El docker-compose.yml declara explícitamente ambas redes en el servicio lightdash:

networks:
  - default
  - postgres-warehouse_default
networks:
  default: {}
  postgres-warehouse_default:
    external: true

Esto no es opcional ni cosmético: sin esto, cualquier docker compose up -d que recree el contenedor (cambiar una env var, actualizar la imagen) lo deja sin poder resolver postgres-dw — pasó dos veces durante el despliegue inicial (detalle completo en el cierre técnico enlazado arriba) hasta declararlo así.

Conexión a trivasa_dw

El proyecto Lightdash (“Trivasa BI”) usa warehouseConnection.type: postgres apuntando a postgres-dw:5432 (nombre interno de contenedor, no localhost), db trivasa_dw, schema analytics, con sslmode: disable explícito — postgres-dw no tiene SSL habilitado y tanto el backend de Lightdash como el CLI local (vía ~/.dbt/profiles.yml, que también necesita sslmode: disable) intentan negociar SSL por default si no se lo desactiva a mano.

Proyecto dbt

trivasa-bi-dev/dbt/trivasa_dbt/ — modelos propios sobre las tablas raw.* de Warehouse Postgres, venv en trivasa-bi-dev/dbt/venv/. Dos capas:

  • staging/ (14 modelos, vistas, schema analytics_staging) — 1:1 con raw.*, renombra columnas del ERP (pr_cve_producto → producto_id, etc.) sin lógica de negocio.
  • marts/ (6 modelos, schema analytics_marts) — dim_producto, fct_compras, fct_ordenes_compra, fct_movimientos (vista, no tabla — ver nota abajo), fct_existencias, fct_gastos_cfdi. Cada columna de dimensión/métrica lleva meta.dimension/meta.metrics en models/marts/_marts.yml — es lo que Lightdash lee para construir los “explores” (una tabla explorable con dimensiones y métricas navegables desde la UI, sin escribir SQL).

fct_movimientos es vista, no tabla, a propósito: es un LEFT JOIN sobre movimiento (4.5M filas) que como tabla física agota el disco de este host (48GB, casi siempre >85% usado) al materializarse. Ver Warehouse Postgres § movimiento para el mismo tipo de límite de recursos en el pipeline de ingesta.

Los 14 modelos de staging/ quedan expuestos como “explores” en Lightdash sin dimensiones/métricas propias (solo son insumo de los marts) — Lightdash los lista igual y los marca en rojo si se abren (“No dimensions available”). Es cosmético, no bloquea nada; no hay forma limpia de excluirlos del listado sin recompilar solo un subconjunto del proyecto dbt (no se investigó a fondo, ver cierre técnico).

Cómo desplegar un cambio de modelo

# 1. Materializar el cambio en Postgres — el paso que se olvida
export PATH="/home/ealcocer/trivasa-bi-dev/dbt/venv/bin:$PATH"
cd ~/trivasa-bi-dev/dbt/trivasa_dbt
dbt run --select <modelo>
 
# 2. Recompilar y subir el manifest a Lightdash (esto NO ejecuta el modelo en Postgres)
npx --yes @lightdash/cli@latest --non-interactive deploy \
  --project 82df3b0a-4b56-4dee-837b-20706bae801b \
  --project-dir . --profiles-dir ~/.dbt --ignore-errors -y

lightdash deploy compila (dbt compile/dbt list), no ejecuta (dbt run). Confundir los dos pasos fue exactamente el bug que rompió fct_movimientos en producción varios días después del despliegue inicial — el modelo se cambió a vista, se hizo deploy, pero nunca se corrió dbt run, así que la vista física no existía en Postgres hasta que el dashboard en vivo tiró relation "analytics_marts.fct_movimientos" does not exist. Detalle completo en el cierre técnico.

Acceso

  • URL pública: https://dash.frento.com.mx (Cloudflare Tunnel, mismo túnel ctunlinux que el resto de los servicios de este host — ver ctunlinux § Túnel de Cloudflare).
  • Usuario admin: ehalsou@gmail.com. Contraseña en trivasa-bi-dev/lightdash/.env (ADMIN_PASS=, permisos 600) — no transcrita aquí.
  • Organización: “Trivasa” (organizationUuid 11f2bdfd-3ba4-4cea-92db-5f878689c262), ALLOW_MULTIPLE_ORGS=false.
  • Proyecto activo: “Trivasa BI”, projectUuid: 82df3b0a-4b56-4dee-837b-20706bae801b. Existe un proyecto anterior huérfano (mismo nombre, sin sslmode configurado, nunca funcional, 0 explores) que quedó sin borrar porque no existe endpoint de borrado de proyecto en esta versión de la API — ignorar si aparece en la UI.
  • Space: “Trivasa” (a7a60416-2048-4f79-9ec4-3b447864b25f) — contiene los 3 dashboards, ver Dashboards demo con Lightdash.
  • CLI: se invoca vía npx --yes @lightdash/cli@latest (no instalado global) — usa un Personal Access Token generado con descripción cli-deploy, gestionable desde la UI (avatar → Personal access tokens) si hace falta rotarlo o generar uno nuevo.

Gotcha: SECURE_COOKIES y sesión por API/curl

El servicio corre con SECURE_COOKIES=true (correcto, está detrás de HTTPS). Esto marca la cookie de sesión como Secure, y curl no la guarda ni la reenvía sobre http://localhost:8090 en plano — cualquier trabajo de API por curl contra el puerto local falla en silencio (login “exitoso” pero sin cookie persistida). Dos salidas: autenticar contra https://dash.frento.com.mx directo, o bajar SECURE_COOKIES=false temporalmente + reiniciar el contenedor + volver a subirlo + reiniciar otra vez al terminar — esta segunda vía fue la que gatilló el bug de red de arriba (cada reinicio recrea el contenedor y depende de que las redes estén declaradas en el compose).

Actualización 2026-08-26: deployment migró a ~/stack/lightdash/, imagen slim

El docker-compose.yml de este servicio ya no vive en trivasa-bi-dev/lightdash/ (esa carpeta no existe más en ctunlinux) sino en ~/stack/lightdash/ — directorio suelto en el home de ealcocer, fuera de cualquier repo git, según la convención de trivasa-bi-core de mantener la config operativa de la máquina separada del código (ver ctunlinux). No confundir con el scaffold sin adoptar trivasa-bi-dev/stack/lightdash/ que describe Stack de BI explorado, no adoptado — son tres rutas distintas a lo largo del tiempo (trivasa-bi-dev/stack/lightdash/ → scaffold nunca usado; trivasa-bi-dev/lightdash/ → producción real 2026-08-09, descrita en el resto de esta página; ~/stack/lightdash/ → producción real actual). El proyecto activo en Lightdash también cambió: trivasa_dw (uuid df98464b-9806-49f2-b5cb-2f99d47905ad), con dbt_connection_type: none — el manifest se sube por lightdash deploy desde el CLI de trivasa-bi-core/dbt/, no por integración GitHub/GitLab. No se reconfirmaron los detalles de “Conexión a trivasa_dw”, “Proyecto dbt” ni “Acceso” de abajo contra este proyecto nuevo — probablemente desactualizados, pendiente de revisión; el contexto operativo vivo y mantenido de esta migración está en trivasa-context/docs/arquitectura/stack-bi.md (repo aparte, ver CLAUDE.md de este mismo repo sobre por qué existen los dos).

La cifra de imagen de la sección “Arquitectura” quedó obsoleta. Medido de nuevo ese mismo día contra la imagen real pulled (lightdash/lightdash:latest, versión 1.129.0): 13.9GB, no 14.1GB — variación esperable entre builds de distintas fechas, mismo orden de magnitud. Lo que sí cambió de fondo es la conclusión: sí existe una forma de recortar esa imagen sin compilar Lightdash desde su código fuente. ~/stack/lightdash/dockerfile.slim-dbt reusa el build oficial (/usr/app + entrypoint, copiados por multi-stage FROM lightdash/lightdash:1.129.0 AS upstream) y solo reinstala, de cero, dbt-core 1.12 + dbt-postgres (265MB) en vez de las 9 versiones de dbt con 7-9 adaptadores cada una (7.5GB de los 13.9GB originales) — este proyecto usa únicamente Postgres, así que el resto es peso muerto. Imagen resultante: 4.77GB (-66%), contenedor sano, sin tocar lightdash-db. Detalle completo (incluidos los gotchas de disco/red del build) en trivasa-context/docs/arquitectura/stack-bi.md.

Véase también