Instalar Langfuse con Docker: Alternativa Self-Hosted a LangSmith
Instala Langfuse con Docker Compose en tu propio servidor. Alternativa self-hosted a LangSmith: imágenes v4, secretos .env, Cloudflare Tunnel, actualizaciones y backups.
Actualizado Publicado 34 min de lectura

Esta guía instala Langfuse v4 con Docker Compose en tu propio servidor: una alternativa self-hosted a LangSmith que mantiene las trazas LLM, los costes y las evaluaciones en hardware que controlas. Langfuse es una plataforma open-source de ingeniería LLM con observabilidad, analítica, gestión de prompts, evaluaciones y experimentos con datasets en un solo stack. Está en 35,6k estrellas de GitHub (comprobado 10-10-2026), y el equipo se ha unido a ClickHouse, lo que importa porque ClickHouse es el motor de analítica debajo.
La cuestión de la versión primero, porque decide todo lo demás: Langfuse v4.0.0 salió el 29-07-2026 y v4.56.0 llegó el 09-10-2026. Langfuse v3 recibe solo parches de seguridad hasta finales de enero de 2027. Las instalaciones nuevas nunca deberían empezar en v3 ahora. Si ya corres v3, la sección de actualización de abajo recorre la migración; la infraestructura no cambia.
v3 está en fin de vida (solo parches de seguridad)
Langfuse v3 recibe parches de seguridad solo hasta finales de enero de 2027. Las instalaciones nuevas deberían usar imágenes v4. Las instalaciones v3 existentes deberían planear la actualización antes de esa fecha, mira Actualizar una instalación Langfuse v3 existente a v4.
Funciones:
- Observabilidad cubre instrumentar tu aplicación e ingerir trazas para ver cómo se comportan tus llamadas LLM, con búsqueda de texto completo sobre inputs, outputs y metadatos.
- Analítica rastrea coste, latencia y calidad mediante dashboards y exportaciones de datos.
- Gestión de prompts versiona y despliega prompts desde dentro de Langfuse.
- Evaluaciones puntúan completados con evals basadas en modelo, feedback de usuarios y puntuación manual.
- Experimentación corre datasets contra tu app antes de lanzar, y compara ejecuciones.
- Integraciones funcionan con LangChain, LlamaIndex, LiteLLM y otros frameworks LLM populares. Si quieres un único gateway delante de tus proveedores, puedes instalar LiteLLM con Docker Compose y enrutar llamadas LLM a través de LiteLLM, trazándolas en Langfuse.
Qué hay de nuevo en Langfuse v4 (y por qué las instalaciones nuevas deberían saltarse v3)
v4 es mayormente un cambio de motor, no una reescritura del producto. El mayor cambio es el modelo de datos ClickHouse: los eventos aterrizan en events_full (filas anchas inmutables) con una proyección events_core optimizada para consultas encima. Las trazas ahora son spans raíz dentro de la misma tabla (span ID t-<trace_id>), y la superficie principal de la UI es una vista única de Observations, abierta filtrada a Is Root Observation = true. Si tienes capturas o memoria muscular de la tabla de trazas de v3, espera una primera pantalla distinta.
Lo que ese modelo de datos desbloquea para self-hosters (estas fueron primero funciones de Langfuse Cloud):
- Búsqueda de texto completo sobre inputs, outputs y metadatos, más una barra de búsqueda con filtros.
- Monitores y alertas sobre métricas de trazas.
- Observations API v2 y Metrics API v2 para exportaciones de datos más limpias.
- Agente en la app movido fuera de la edición enterprise a beta pública.
- Mejor ergonomía de self-hosting en el compose oficial: inicialización headless vía
LANGFUSE_INIT_*,LANGFUSE_AI_*para el asistente en la app y modelos de eval,LANGFUSE_MCP_*para el servidor MCP,LANGFUSE_S3_BATCH_EXPORT_*, yREDIS_TLS_*.
Novedades de v4
- Nuevo modelo ClickHouse (
events_full+events_core), trazas como observaciones raíz - Búsqueda de texto completo, barra de búsqueda con filtros, monitores y alertas
- Observations API v2 y Metrics API v2
- Agente en la app en beta pública
- Init headless, servidor MCP, bloques env de exportación por lotes en el compose oficial
- Ruta de escritura directa del SDK (Python SDK >= 4.7.0, JS/TS SDK >= 5.4.0)
Lo que sigue igual
- Los mismos seis servicios:
langfuse-web,langfuse-worker, PostgreSQL, ClickHouse, Redis, S3/MinIO - Las variables env requeridas:
NEXTAUTH_URL,NEXTAUTH_SECRET,SALT,ENCRYPTION_KEY,DATABASE_URL,CLICKHOUSE_*,REDIS_* - El flujo Docker Compose: un archivo compose, un
.env,docker compose up -d AUTH_DISABLE_SIGNUP, opt-out de telemetría, endpoints de salud- Solo cambiaron las versiones mínimas (ClickHouse >= 25.12, PostgreSQL 15+, Redis 7+)
Sobre las cifras de rendimiento
La guía oficial de actualización afirma que los tiempos de carga del dashboard para proyectos grandes mejoran “10x o más”; el banner de marketing dice hasta 165x. No hemos medido estas cifras, vienen de los propios materiales de Langfuse comprobados el 10-10-2026. Tu kilometraje depende del hardware y el volumen de trazas.
¿Por qué saltarse v3 por completo? Está en modo mantenimiento con una fecha de fin de soporte dura, y v4 corre sobre la infraestructura idéntica. La propia FAQ de la guía de actualización responde “¿Necesito nuevos componentes de infraestructura?” con “No.” Los mismos contenedores web y worker, el mismo PostgreSQL, ClickHouse, Redis y S3. Empezar en v3 hoy significa hacer la migración después sin beneficio. Si ya estás en v3, lee la sección de actualización y la guía oficial de actualización v3 a v4. El historial de releases vive en GitHub releases.
Guía paso a paso para instalar Langfuse con Docker Compose
El recorrido de abajo cubre la instalación completa de Langfuse con Docker: archivo compose, secretos, verificación, HTTPS y backups. Si prefieres vídeo:
Vídeo grabado en v3
El recorrido incrustado se grabó sobre la UI de v3, así que las capturas difieren de lo que verás en v4. Los pasos de compose y .env son los mismos; solo cambiaron los tags de imagen y la vista de observaciones. El artículo de abajo refleja v4 (comprobado 10-10-2026).
Si quieres vigilar CPU, memoria y disco mientras corre este stack, monta primero cómo monitorizar recursos del servidor y Docker. Langfuse es uno de los stacks compose más pesados que self-hostearás, y te dirá cuándo la máquina es demasiado pequeña.
1. Prerequisitos y dimensionado del VPS para Langfuse v4
Antes de empezar, ten esto en su sitio:
- Un VPS o home server. Uso Hetzner o Hostinger para máquinas VPS; para un home server, un mini PC como el ASUS DC510 funciona bien. Mira los mejores mini PCs para home server si aún eliges hardware.
- Docker Engine con el plugin Compose v2 (
docker compose versiondebe funcionar). Si quieres una UI para el stack, usa Dockge, un gestor de Docker Compose para self-hosting. - Un dominio o subdominio apuntando al servidor (por ejemplo
langfuse.yourdomain.com). - Una ruta de reverse proxy: CloudPanel como reverse proxy con Docker y Dockge, cómo usar Traefik como reverse proxy en Docker, o Cloudflare Tunnels (cubierto en el paso 5).
- Puertos del host libres:
5061(UI web) y, si quieres health checks del lado del host,3030(worker). Comprueba conss -tlnp | grep -E ‘5061|3030’. - Al menos 50 GB de disco libre. ClickHouse y MinIO crecen con el volumen de trazas, y el backfill de v3 a v4 quiere margen.
Dimensionado: el ejemplo oficial es 4 núcleos / 16 GiB RAM / 100 GiB de disco
El propio ejemplo Docker Compose de Langfuse usa una VM de 4 núcleos, 16 GiB RAM y 100 GiB de disco (un t3.xlarge en términos AWS, aproximadamente una máquina clase Hetzner CPX41, del orden de 15-25 €/mes). La guía de contenedores para producción es al menos 2 CPU y 4 GB RAM por contenedor. Una máquina de 8 GB puede funcionar para volumen de hobby, pero está por debajo del ejemplo oficial y no la hemos probado. El heap de Node.js va por defecto a 1,7 GiB, así que el .env de abajo pone NODE_OPTIONS=–max-old-space-size=4096. Vigila la memoria tras desplegar con cómo monitorizar recursos del servidor y Docker.
Los precios de VPS saltaron en bloque en 2026. Si estás replanteándote una máquina alquilada, mira qué cambió y cuándo gana un mini PC.
2. Archivo Docker Compose de Langfuse (imágenes v4)
El stack v4 son seis servicios, misma forma que v3:
- langfuse-worker procesa eventos de trazas de la cola, los escribe en ClickHouse, y corre trabajos en segundo plano incluyendo el backfill histórico.
- langfuse-web sirve la UI y las APIs públicas en el puerto 5061 del host. Este es el contenedor al que apunta tu reverse proxy.
- postgres es la base de datos transaccional (PostgreSQL 17) para usuarios, organizaciones, proyectos, prompts y claves API.
- clickhouse es el almacén OLAP para eventos y analítica. Aquí es donde vive el modelo de datos v4 (
events_full+events_core). - minio es almacenamiento de blobs compatible con S3 para payloads de eventos (
events/) y medios multi-modal (media/). - redis mantiene la cola de ingestión y la caché. Perderlo te cuesta eventos encolados, no tu base de datos.
Crea un directorio para el stack y suelta este archivo compose:
mkdir -p /opt/langfuse && cd /opt/langfuseservices:
langfuse-worker:
image: langfuse/langfuse-worker:4
restart: always
depends_on:
postgres:
condition: service_healthy
minio:
condition: service_healthy
redis:
condition: service_healthy
clickhouse:
condition: service_healthy
ports:
- 127.0.0.1:3030:3030 # worker health endpoint (new vs the old v3 file)
environment:
DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}
NEXTAUTH_URL: https://langfuse.yourdomain.com
SALT: ${SALT}
ENCRYPTION_KEY: ${ENCRYPTION_KEY}
NODE_OPTIONS: --max-old-space-size=4096
TELEMETRY_ENABLED: false
CLICKHOUSE_MIGRATION_URL: clickhouse://clickhouse:9000
CLICKHOUSE_URL: http://clickhouse:8123
CLICKHOUSE_USER: ${CLICKHOUSE_USER}
CLICKHOUSE_PASSWORD: ${CLICKHOUSE_PASSWORD}
LANGFUSE_S3_EVENT_UPLOAD_BUCKET: langfuse
LANGFUSE_S3_EVENT_UPLOAD_REGION: auto
LANGFUSE_S3_EVENT_UPLOAD_ACCESS_KEY_ID: ${MINIO_ROOT_USER}
LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY: ${MINIO_ROOT_PASSWORD}
LANGFUSE_S3_EVENT_UPLOAD_ENDPOINT: http://minio:9000
LANGFUSE_S3_EVENT_UPLOAD_FORCE_PATH_STYLE: true
LANGFUSE_S3_EVENT_UPLOAD_PREFIX: events/
LANGFUSE_S3_MEDIA_UPLOAD_BUCKET: langfuse
LANGFUSE_S3_MEDIA_UPLOAD_REGION: auto
LANGFUSE_S3_MEDIA_UPLOAD_ACCESS_KEY_ID: ${MINIO_ROOT_USER}
LANGFUSE_S3_MEDIA_UPLOAD_SECRET_ACCESS_KEY: ${MINIO_ROOT_PASSWORD}
LANGFUSE_S3_MEDIA_UPLOAD_ENDPOINT: http://minio:9000
LANGFUSE_S3_MEDIA_UPLOAD_FORCE_PATH_STYLE: true
LANGFUSE_S3_MEDIA_UPLOAD_PREFIX: media/
REDIS_HOST: redis
REDIS_PORT: 6379
REDIS_AUTH: ${REDIS_PASSWORD}
langfuse-web:
image: langfuse/langfuse:4
restart: always
depends_on:
postgres:
condition: service_healthy
minio:
condition: service_healthy
redis:
condition: service_healthy
clickhouse:
condition: service_healthy
ports:
- 5061:3000
environment:
DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}
NEXTAUTH_URL: https://langfuse.yourdomain.com
NEXTAUTH_SECRET: ${NEXTAUTH_SECRET}
SALT: ${SALT}
ENCRYPTION_KEY: ${ENCRYPTION_KEY}
NODE_OPTIONS: --max-old-space-size=4096
TELEMETRY_ENABLED: false
CLICKHOUSE_MIGRATION_URL: clickhouse://clickhouse:9000
CLICKHOUSE_URL: http://clickhouse:8123
CLICKHOUSE_USER: ${CLICKHOUSE_USER}
CLICKHOUSE_PASSWORD: ${CLICKHOUSE_PASSWORD}
LANGFUSE_S3_EVENT_UPLOAD_BUCKET: langfuse
LANGFUSE_S3_EVENT_UPLOAD_REGION: auto
LANGFUSE_S3_EVENT_UPLOAD_ACCESS_KEY_ID: ${MINIO_ROOT_USER}
LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY: ${MINIO_ROOT_PASSWORD}
LANGFUSE_S3_EVENT_UPLOAD_ENDPOINT: http://minio:9000
LANGFUSE_S3_EVENT_UPLOAD_FORCE_PATH_STYLE: true
LANGFUSE_S3_EVENT_UPLOAD_PREFIX: events/
LANGFUSE_S3_MEDIA_UPLOAD_BUCKET: langfuse
LANGFUSE_S3_MEDIA_UPLOAD_REGION: auto
LANGFUSE_S3_MEDIA_UPLOAD_ACCESS_KEY_ID: ${MINIO_ROOT_USER}
LANGFUSE_S3_MEDIA_UPLOAD_SECRET_ACCESS_KEY: ${MINIO_ROOT_PASSWORD}
LANGFUSE_S3_MEDIA_UPLOAD_ENDPOINT: http://minio:9000
LANGFUSE_S3_MEDIA_UPLOAD_FORCE_PATH_STYLE: true
LANGFUSE_S3_MEDIA_UPLOAD_PREFIX: media/
REDIS_HOST: redis
REDIS_PORT: 6379
REDIS_AUTH: ${REDIS_PASSWORD}
AUTH_DISABLE_SIGNUP: ${AUTH_DISABLE_SIGNUP}
postgres:
image: postgres:17-alpine
restart: always
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 5s
timeout: 5s
retries: 5
start_period: 10s
volumes:
- ./langfuse-db:/var/lib/postgresql/data:rw
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
clickhouse:
image: clickhouse/clickhouse-server:25.12 # pinned: v4 minimum is 25.12, 26.4 recommended
restart: always
user: "101:101"
ports:
- 127.0.0.1:8123:8123 # localhost only
- 127.0.0.1:9000:9000
environment:
CLICKHOUSE_DB: default
CLICKHOUSE_USER: ${CLICKHOUSE_USER}
CLICKHOUSE_PASSWORD: ${CLICKHOUSE_PASSWORD}
volumes:
- ./langfuse-clickhouse:/var/lib/clickhouse
- ./langfuse-clickhouse-logs:/var/log/clickhouse-server
healthcheck:
test: wget --no-verbose --tries=1 --spider http://localhost:8123/ping || exit 1
interval: 5s
timeout: 5s
retries: 10
start_period: 30s
minio:
image: cgr.dev/chainguard/minio
restart: always
entrypoint: sh
command: -c 'mkdir -p /data/langfuse && minio server --address ":9000" --console-address ":9001" /data'
environment:
MINIO_ROOT_USER: ${MINIO_ROOT_USER}
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
ports:
- 127.0.0.1:9090:9000 # localhost only
- 127.0.0.1:9091:9001 # MinIO console, localhost only
volumes:
- ./langfuse-minio:/data
healthcheck:
test: ["CMD", "mc", "ready", "local"]
interval: 1s
timeout: 5s
retries: 5
start_period: 10s
redis:
image: redis:7
restart: always
command: >
--requirepass ${REDIS_PASSWORD}
--maxmemory-policy noeviction
ports:
- 127.0.0.1:6379:6379 # localhost only, for debugging
volumes:
- langfuse_redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 3s
timeout: 10s
retries: 10
start_period: 5s
volumes:
langfuse_redis_data:Qué cambió frente al archivo viejo (v3)
- Tags de imagen:
langfuse/langfuse:3ylangfuse/langfuse-worker:3pasan a:4. - ClickHouse ahora está fijado en
clickhouse/clickhouse-server:25.12(antes flotaba enlatest, que es exactamente el tipo de deriva que rompe un stack meses después). - El worker publica
127.0.0.1:3030para que puedas pegarle a su endpoint de salud. - Redis obtiene un volumen nombrado persistente; los puertos de ClickHouse, MinIO y Redis están enlazados a localhost en vez de al mundo.
- Las credenciales MinIO usan los nombres oficiales
MINIO_ROOT_USER/MINIO_ROOT_PASSWORD. NODE_OPTIONSsubido a 4 GiB para igualar la guía de contenedores.
Una nota sobre registries, ya que el compose oficial hace pull desde docker.langfuse.com:
Imágenes de Docker Hub
El archivo de arriba usa langfuse/langfuse:4 y langfuse/langfuse-worker:4 de Docker Hub. Más simple de leer, funciona bien.
Registry oficial
El compose oficial hace pull de docker.langfuse.com/langfuse/langfuse:4. Ese host es un espejo de Docker Hub (hace 307-redirect a registry-1.docker.io), así que las imágenes son idénticas. Usa esto si tu organización lista el registry de Langfuse en la allowlist.
Notas sobre el archivo:
- Las variables de entorno (
${VARIABLE_NAME}) mantienen secretos y hostnames fuera del YAML. La siguiente sección los genera. - Todos los servicios de respaldo tienen healthchecks con
start_period, y los contenedores Langfuse esperan a dependencias sanas antes de arrancar. - Los bind mounts (
./langfuse-db,./langfuse-clickhouse,./langfuse-minio) mantienen los datos en el filesystem del host. Prefiero bind mounts aquí frente a volúmenes nombrados: son triviales de empaquetar en tar en la sección de backups y triviales de inspeccionar cuando algo se rompe. - Telemetría desactivada. El default de compose de Langfuse es ahora
true, así que mantén esta línea si no quieres estadísticas phone-home. - Los prefijos S3
events/ymedia/están puestos explícitamente; el servidor tiene los mismos defaults, así que esto es documentación más que configuración. - Para despliegues reproducibles, fija la versión de patch exacta (por ejemplo
langfuse/langfuse:4.56.0, actual al 10-10-2026). El tag:4sigue el minor actual y se parchea aproximadamente a diario. Vigila los GitHub releases de cualquier modo.
La referencia completa de cada variable vive en los docs oficiales de configuración self-hosting. El archivo upstream contra el que hacer diff es el docker-compose.yml oficial de Langfuse.
3. El archivo .env: secretos y variables LANGFUSE_INIT opcionales
Crea .env junto al archivo compose:
POSTGRES_USER='langfuse'
POSTGRES_PASSWORD='change-me-strong'
POSTGRES_DB='langfuse'
NEXTAUTH_SECRET=
SALT=
ENCRYPTION_KEY=
CLICKHOUSE_USER=clickhouse
CLICKHOUSE_PASSWORD=change-me-strong
MINIO_ROOT_USER=minio
MINIO_ROOT_PASSWORD=change-me-strong
REDIS_PASSWORD=change-me-strong
AUTH_DISABLE_SIGNUP=falseGenera los tres secretos y pégalos. No deben ser adivinables, y ENCRYPTION_KEY tiene un formato fijo:
openssl rand -base64 32→NEXTAUTH_SECRETopenssl rand -base64 32→SALTopenssl rand -hex 32→ENCRYPTION_KEY(exactamente 64 caracteres hex)
openssl rand -base64 32
openssl rand -base64 32
openssl rand -hex 32Luego bloquea el archivo:
chmod 600 .envTrata .env como un secreto de producción
Nunca lo subas a control de versiones y nunca lo pegues en un chat. ENCRYPTION_KEY protege credenciales de conexión sensibles: si lo pierdes, los valores cifrados en la base de datos no pueden descifrarse. Haz backup de .env junto con los volúmenes de datos (mira la sección de backups) o los backups son solo media ruta de restauración.
Inicialización headless opcional: si prefieres no hacer clic por el registro de primer arranque, Langfuse puede pre-crear la organización, el proyecto, las claves API y el primer usuario desde variables env al arrancar. Añade esto a .env:
# Optional: headless initialization (skip the UI first-run flow)
# LANGFUSE_INIT_ORG_NAME=My Org
# LANGFUSE_INIT_PROJECT_NAME=default
# LANGFUSE_INIT_PROJECT_PUBLIC_KEY=pk-lf-...
# LANGFUSE_INIT_PROJECT_SECRET_KEY=sk-lf-...
# LANGFUSE_INIT_USER_EMAIL=you@yourdomain.com
# LANGFUSE_INIT_USER_PASSWORD=change-me-strongDéjalas comentadas y el primer usuario se crea desde la página de registro en su lugar. Ambos caminos valen; el init headless es mejor cuando automatizas despliegues y quieres una clave API impresa en logs en vez de cliqueada. Detalles en los docs de inicialización headless.
4. Desplegar el stack y verificar que está sano
Arranca todo desde el directorio con el archivo compose:
docker compose up -dEso baja imágenes, crea contenedores y los arranca en segundo plano. Comprueba que existen:
docker compose psLos seis servicios deberían reportar running, y los cuatro servicios de respaldo deberían pasar a healthy en cosa de un minuto.
El primer arranque tarda 2-3 minutos
Las migraciones corren al inicio. El contenedor web imprime Ready cuando termina. No reinicies a mitad de migración, y no entres en pánico si la UI está en blanco los primeros minutos.
Vigila el contenedor web hasta que esté listo:
docker compose logs -f langfuse-webLa señal de éxito es una línea de log Ready. Luego golpea los endpoints de salud:
# web: expect {"success":true}
curl -s http://localhost:5061/api/public/health | jq
# web with DB check: expect {"success":true}
curl -s "http://localhost:5061/api/public/health?failIfDatabaseUnavailable=true" | jq
# readiness: expect 200
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:5061/api/public/ready
# worker: expect {"success":true}
curl -s http://localhost:3030/api/health | jqdocker compose ps: seis servicios corriendo, servicios de respaldo healthydocker compose logs langfuse-web: líneaReadypresente/api/public/healthdevuelve{"success":true}curl localhost:3030/api/healthdevuelve{"success":true}- La UI carga en
http://your-server-ip:5061(antes de que el tunnel esté arriba)
La referencia oficial de endpoints es el doc de endpoints de salud y readiness. Dos modos de fallo aparecen aquí más a menudo: una dependencia atascada en unhealthy (casi siempre credenciales malas en .env, revisa docker compose logs postgres o clickhouse), y el puerto 5061 del host ya ocupado (ss -tlnp | grep 5061, luego cambia el puerto del host en el archivo compose). Más de estos en la sección de troubleshooting.
5. HTTPS con Cloudflare Tunnels
Cloudflare Tunnels conectan tu app a internet sin abrir puertos entrantes en el servidor. El daemon cloudflared marca hacia la red de Cloudflare y mantiene un tunnel persistente a tu origen. Las peticiones a tu dominio bajan por ese tunnel a tu servidor, y las respuestas suben por él. Sin port forwarding, sin agujeros de firewall.
En el panel de Cloudflare Zero Trust, ve a Access - Tunnels, elige tu tunnel, y añade un hostname que mapee tu subdominio al servicio y puerto (http://langfuse-web:3000 si el tunnel corre en la misma red Docker, o http://localhost:5061 si corre en el host).

Verifica desde tu estación de trabajo:
curl -I https://langfuse.yourdomain.comDeberías obtener un 302 o 200 apuntando a la página de login de Langfuse, no un error de Cloudflare. Si ves un 502, el tunnel no puede alcanzar el puerto de origen.
NEXTAUTH_URL debe coincidir con la URL pública
Lo que pongas en NEXTAUTH_URL debe ser exactamente la URL que los usuarios escriben en el navegador, incluyendo https. Un desajuste es la causa clásica de bucles de redirección de login tras montar el tunnel.
Alternativamente, puedes usar Setup CloudPanel as Reverse Proxy with Docker and Dockge o How to Use Traefik as A Reverse Proxy in Docker.
6. Primer login: crea tu cuenta de admin (o haz init headless)
Sin cuenta de admin por defecto
Langfuse se entrega sin ningún login. La primera cuenta creada por la página de registro se convierte en la admin. Si los registros ya están desactivados y no tienes cuenta, quedarás fuera, así que crea la admin antes de activar AUTH_DISABLE_SIGNUP.
Crear admin en la UI (default)
- Abre
https://langfuse.yourdomain.com. - Usa la opción de registro en la página de login. El primer usuario se convierte en la admin.
- Crea un proyecto, luego abre los ajustes del proyecto y genera una clave API (par de clave pública + secreta).
- Apunta el SDK de tu app a la instancia y empieza a enviar trazas.
Init headless vía LANGFUSE_INIT_*
- Pon las variables
LANGFUSE_INIT_*en.envantes del primer arranque (sección anterior). docker compose up -dcrea la organización, el proyecto, las claves API y el primer usuario.- Entra con
LANGFUSE_INIT_USER_EMAIL/LANGFUSE_INIT_USER_PASSWORD. - Rota la clave secreta generada si la generaste fuera de Langfuse.
Una vez dentro, el ciclo de despliegue está cerrado: proyecto creado, clave API generada, listo para trazar. En v4 la pantalla principal es la vista de Observations filtrada a observaciones raíz, no la vieja tabla de trazas de v3, así que las capturas más viejas pueden resultar extrañas.
Puedes integrarlo con tus apps IA a continuación. El vídeo incrustado muestra la integración con Flowise; para la otra mitad de ese stack mira cómo instalar FlowiseAI con Docker Compose.

Actualizar una instalación Langfuse v3 existente a v4
Si seguiste la versión vieja de esta guía, la actualización son tres pasos y puedes pausar entre ellos. No es una instalación nueva: tus datos se quedan en los mismos bind mounts. El detalle completo vive en la guía oficial de actualización v3 a v4; esto es el resumen para operadores.
Haz backup antes de actualizar
Las migraciones v4 no son reversibles cambiando las imágenes de vuelta a :3. Después de que el schema migra, un simple cambio a imagen v3 falla con no migration found for version 46. Haz un backup completo (Postgres + ClickHouse + MinIO + .env) antes de tocar las imágenes. Mira hacer backup de tus volúmenes Docker de Langfuse.
Paso 1: actualiza ClickHouse primero, aún en v3. v4 necesita ClickHouse >= 25.12 (26.4 recomendado) para lightweight updates, el tipo JSON y la búsqueda de texto completo. Las releases v3 actuales son compatibles con ClickHouse actual, así que sube la imagen en el stack v3 corriendo:
clickhouse:
image: clickhouse/clickhouse-server:25.12docker compose up -d clickhouse
docker compose ps # clickhouse must go healthy before you continuePaso 2: sube las imágenes del servidor a v4. Cambia langfuse/langfuse:3 y langfuse/langfuse-worker:3 a :4, luego:
docker compose pull
docker compose up -dLas migraciones de schema corren automáticamente al arrancar. Los datos históricos se re-rellenan en segundo plano, de más nuevo a más viejo. El backfill es reanudable, pero necesita espacio de trabajo.
Margen de disco para el backfill
El backfill histórico usa una tabla de trabajo y necesita del orden de 3x tu uso de disco actual de ClickHouse hasta que se limpie. Si el disco está justo, añade espacio primero: añade un nuevo disco a Ubuntu LVM y móntalo permanentemente.
El comportamiento de escritura durante la migración se controla con variables env que puedes poner en ambos contenedores:
| Variable | Valores | Default | Qué controla |
|---|---|---|---|
LANGFUSE_MIGRATION_V4_WRITE_MODE |
legacy, dual, events_only |
events_only |
Qué pipelines aceptan escrituras. En modo dual, los datos de SDKs viejos aparecen con unos 15 minutos de retardo (pipeline de staging). |
LANGFUSE_MIGRATION_V4_NATIVE_OTEL_BEHAVIOUR |
ver guía de actualización | - | Comportamiento de ingestión OTEL nativa durante la migración. |
LANGFUSE_MIGRATION_V4_ALLOW_PREVIEW_OPT_IN |
ver guía de actualización | - | Opt-in para rutas de ingestión de preview. |
LANGFUSE_BACKGROUND_MIGRATION_V4_ENABLE_HISTORIC_BACKFILL |
true, false |
true |
Backfill en segundo plano de datos históricos al nuevo modelo. |
LANGFUSE_BACKGROUND_MIGRATION_V4_DROP_PID_TID_SORTING_TABLES |
true, false |
ver guía de actualización | Limpieza de viejas tablas de ordenación tras el backfill. |
Si corre un periodo de escritura dual, comprueba la sonda de propagación del worker (espera la publicación de puerto 127.0.0.1:3030 del archivo compose de arriba):
curl -s "http://localhost:3030/api/health?failIfEventPropagationStuck=true" | jqUn 503 significa que la propagación de eventos lleva atascada más de 15 minutos. Arréglalo antes del cutover.
Paso 3: cutover, el punto de no retorno. Actualiza primero tus SDKs: la escritura directa necesita Python SDK >= 4.7.0 y JS/TS SDK >= 5.4.0. Los clientes Python v2 y JS/TS v3 son rechazados una vez que estás en la nueva ruta de escritura. Luego mueve los evaluadores a puntuación a nivel de observación, cambia las exportaciones a la fuente “Enriched observations”, y corre con defaults. Desde aquí, un rollback a v3 es un rewind de schema (migrate ... goto 37 desde la imagen web v4 en /app/packages/shared) o una restauración desde tu backup. Prefiere el backup.
La infraestructura en sí no cambió: mismos contenedores web y worker, mismo PostgreSQL, ClickHouse, Redis y S3. Solo se movieron las versiones mínimas (ClickHouse 25.12, PostgreSQL 15, Redis 7.0). Una advertencia honesta: este resumen sigue la guía oficial, pero una actualización de ClickHouse en sitio sobre datos en bind-mount merece una pasada en staging antes de hacerla en algo que te importe.
Troubleshooting: fallos comunes de la instalación Docker de Langfuse
Un contenedor de dependencia se queda unhealthy
Cuando docker compose ps muestra postgres, clickhouse, minio o redis como unhealthy, los contenedores Langfuse nunca arrancan (están bloqueados en service_healthy). Casi siempre son credenciales malas en .env, o un directorio de volumen con propiedad incorrecta (ClickHouse corre como uid 101).
Revisa docker compose logs postgres (o clickhouse, minio, redis) y lee el error de auth. Para bind mounts de ClickHouse: sudo chown -R 101:101 ./langfuse-clickhouse ./langfuse-clickhouse-logs. Luego docker compose up -d para reintentar.
El puerto 5061 o 3030 ya está en uso
docker compose up -d falla con Bind for 0.0.0.0:5061 failed: port is already allocated cuando otro contenedor o servicio del host posee el puerto.
Encuentra al culpable con ss -tlnp | grep -E ‘5061|3030’, luego páralo o remapea el puerto del host (por ejemplo 5062:3000). Mantén NEXTAUTH_URL apuntando a lo que los usuarios navegan.
El contenedor web nunca imprime Ready
Pasan minutos y docker compose logs -f langfuse-web muestra migraciones o errores en vez de Ready. O las migraciones siguen corriendo (dale 2-3 minutos), ClickHouse es más viejo que 25.12 (si actualizaste desde v3 sin subir ClickHouse primero), o el contenedor web no puede alcanzar uno de los servicios de respaldo.
Revisa el final del log para el error real. Confirma que ClickHouse responde: curl -s http://localhost:8123/ping debería imprimir Ok.. Confirma que el host de DATABASE_URL es postgres (el nombre del servicio compose), no localhost.
OOM kills o el proceso Node se queda sin heap
Los contenedores se reinician con código de salida 137, o la UI web muere bajo carga. La máquina es demasiado pequeña (16 GiB es el ejemplo oficial) o el default de heap de Node de 1,7 GiB es demasiado bajo para tu volumen de trazas.
El archivo compose de arriba pone NODE_OPTIONS=–max-old-space-size=4096; súbelo junto con los límites de memoria del contenedor si tienes la RAM. Vigila el uso con cómo monitorizar recursos del servidor y Docker. Si la máquina tiene 8 GB, espera problemas por encima de volumen de hobby y considera redimensionar.
La cola del worker está atascada
Las trazas no aparecen en la UI, pero la API las acepta. El worker dejó de consumir de Redis (a menudo tras un reinicio de Redis o un evento OOM).
curl -s “http://localhost:3030/api/health?failIfQueueConsumptionStuck=true” | jq devuelve 503 si no se ha procesado ningún trabajo en más de 60 minutos. docker compose restart langfuse-worker, luego verifica que llegan nuevas trazas. Los eventos encolados de la ventana de caída pueden perderse, dependiendo de cuándo persistió Redis por última vez.
El login vuelve a la página de registro o redirige mal
Tras levantar el tunnel o reverse proxy, el login te rebota entre la página de login y un error. La causa es que NEXTAUTH_URL no coincide exactamente con la URL pública (esquema, host, barra final).
Pon NEXTAUTH_URL=https://langfuse.yourdomain.com exactamente a lo que los usuarios escriben, luego docker compose up -d (un cambio de env basta; no hace falta pull).
Asegurar tu instancia Langfuse self-hosted
Por defecto, cualquiera que encuentre la URL puede registrarse y crear una cuenta. Después de crear la cuenta de admin, activa el flag en .env:
AUTH_DISABLE_SIGNUP=trueAplica el cambio:
docker compose up -dDesactivar registros también bloquea invitaciones
AUTH_DISABLE_SIGNUP=true bloquea cualquier creación de cuenta nueva, incluyendo usuarios que tienen una invitación de proyecto abierta. Desactívalo temporalmente para incorporar compañeros, luego vuelve a activarlo. No necesitas docker compose pull para un cambio de env; up -d recrea los contenedores con el nuevo valor.
Más opciones de endurecimiento de los docs oficiales de hardening:
AUTH_EMAIL_VERIFICATION_REQUIRED=truesi tienes SMTP configurado.AUTH_SESSION_MAX_AGEcontrola la duración de la sesión (default 43200 minutos, 30 días). Bájalo en máquinas compartidas.AUTH_DOMAINS_WITH_SSO_ENFORCEMENTyAUTH_DISABLE_USERNAME_PASSWORD=truesi corres SSO y quieres que el login con contraseña desaparezca por completo.- Langfuse self-hosted rechaza objetivos privados o de loopback para conexiones LLM configuradas por el usuario y webhooks por defecto (defensa SSRF). Hay overrides
*_WHITELISTED_*si apuntas intencionadamente a un servidor de modelos interno.
- Desactiva registros tras la primera admin
- Valores únicos fuertes en
.env, modo de archivo600, nunca en el repo - Telemetría desactivada si el servidor tiene egress restringido
- Duración de sesión bajada para coincidir con tu modelo de amenaza
- Verificación de email activada si hay SMTP
- Puertos de servicios internos enlazados a
127.0.0.1(como en el archivo compose de arriba)
A nivel de servidor entero, no solo Langfuse: cómo aseguré mi servidor Docker (guía de hardening BSI) cubre el firewall y los agujeros específicos de Docker que importan aquí.
Límite de coste que vale conocer: el núcleo es licencia MIT y gratis para siempre, pero SSO/SAML, RBAC, SCIM y audit logs viven en la edición enterprise y requieren una clave de licencia de pago. Todo lo de esta guía corre sin ella.
Hacer backup de tus volúmenes Docker de Langfuse
Self-hostear significa que los datos son tuyos de perder. El stack escribe en tres bind mounts y un volumen nombrado:
| Ruta | Contiene | Método de backup | Criticidad |
|---|---|---|---|
./langfuse-db |
PostgreSQL: usuarios, orgs, proyectos, prompts, claves API | pg_dump en cron |
Crítica |
./langfuse-clickhouse (+ -logs) |
Trazas, eventos, analítica | Snapshot de volumen o clickhouse-backup |
Crítica |
./langfuse-minio |
Payloads de eventos y blobs de medios | Tar o rclone a almacenamiento compatible con S3 | Alta |
langfuse_redis_data |
Cola y caché | Saltar; reconstruible | Baja |
.env |
Todos los secretos incluyendo ENCRYPTION_KEY |
Copia cifrada fuera del sitio | Crítica |
Los backups de ClickHouse son tu trabajo al self-hostear. La guía oficial de backups dice lo mismo: snapshots de volumen o clickhouse-backup, tú eliges. Un script mínimo programable por cron:
#!/usr/bin/env bash
set -euo pipefail
cd /opt/langfuse
set -a; source ./.env; set +a # export POSTGRES_USER / POSTGRES_DB for pg_dump
STAMP=$(date +%F)
DEST="/backup/langfuse/$STAMP"
mkdir -p "$DEST"
# Postgres logical dump
docker compose exec -T postgres pg_dump -U "$POSTGRES_USER" "$POSTGRES_DB" | gzip > "$DEST/postgres.sql.gz"
# ClickHouse: cold copy of the data dir (stop-free, consistent enough for most self-hosters;
# use clickhouse-backup for stricter consistency)
sudo tar -czf "$DEST/clickhouse.tar.gz" ./langfuse-clickhouse
# MinIO blobs
sudo tar -czf "$DEST/minio.tar.gz" ./langfuse-minio
# Secrets: without these, the volume backups are half a restore
cp .env "$DEST/env.copy"
# Offsite sync (rclone, restic, rsync over SSH, whatever you already trust)
# rclone sync "$DEST" remote:langfuse-backups/"$STAMP"Los backups incluyen .env
Sin ENCRYPTION_KEY y la contraseña de la base de datos, los volcados de los volúmenes no pueden descifrarse ni cargarse. Guarda .env con los backups, cifrado en reposo, en un dominio de fallo distinto al VPS.
.envincluido y guardado cifrado fuera del sitiopg_dumpde Postgres en cron diario- Snapshot de ClickHouse o
clickhouse-backupsemanal, y antes de cada actualización - Volumen de MinIO sincronizado a almacenamiento compatible con S3
- Ensayo de restauración en una máquina de prueba al menos una vez por trimestre
Verifica el backup, no solo el trabajo de backup. Restaura los tres directorios de datos más .env en un directorio compose limpio en otra máquina, corre docker compose up -d, y comprueba que aparecen tus proyectos y trazas. Un backup que nunca has restaurado es una hipótesis. Para la parte offsite, mira configurar backups de Dokploy con Cloudflare R2 (compatible con S3).
Langfuse self-hosted vs LangSmith: precios 2026
La parte de “alternativa a LangSmith” del título es mayormente un argumento de coste y control de datos. Cifras al 10-10-2026:
| Langfuse self-hosted | Langfuse Cloud | LangSmith | |
|---|---|---|---|
| Nivel de entrada | Gratis (núcleo MIT) | Hobby: gratis | Developer: $0 |
| Niveles de pago | Clave de licencia solo para add-ons EE | Core $29/mes, Pro $199/mes, Enterprise $2499/mes | Plus $39/asiento/mes, Enterprise a medida |
| Modelo de uso | Ilimitado, tu hardware | Hobby 50k unidades/mes; Core 100k incluidas, $8/100k extra | Dev 5k trazas base/mes; Plus 10k trazas base |
| Retención | Lo que aguante tu disco | Hobby 30 días, Core 90 días, Pro 3 años | Depende del plan |
| Opción self-hosted | Sí, es esta guía | No | Solo Enterprise |
| Mejor para | Control de datos, volumen y sin facturación por asiento | Pocas ops, arranque rápido | Equipos LangChain que ya pagan por asiento |
Precios comprobados 10-10-2026
Verificado contra langfuse.com/pricing y langchain.com/pricing el 10-10-2026. Las páginas de precios cambian; vuelve a comprobar si lees esto más de un mes después.
La matemática de coste del self-hosting es el VPS más tu tiempo. En una máquina clase CPX41 de Hetzner (orden de magnitud 15-25 €/mes) tienes trazas ilimitadas y usuarios ilimitados, y el trade-off es que posees las actualizaciones y los backups. Cuando un equipo necesita SSO/SAML, RBAC, SCIM o audit logs, esos son features de la edición enterprise que necesitan una clave de licencia de pago encima. La plataforma núcleo de esta guía sigue gratis de todas formas.
Conclusión
Self-hostear Langfuse con Docker Compose te da control total sobre tus datos y corre la misma infraestructura que alimenta Langfuse Cloud. El rendimiento depende de tu hardware, el ejemplo oficial empieza en 4 núcleos y 16 GiB, y los endpoints de salud te dicen rápido cuándo algo va mal.
El resumen para operadores: despliega el stack v4 de seis servicios, verifica con /api/public/health y la sonda del worker, haz backup de los volúmenes más .env antes de necesitarlos, y decide entre el tag flotante :4 y un langfuse/langfuse:4.56.0 fijado (actual 10-10-2026) según quieras parches automáticos o despliegues reproducibles. Si sigues en v3, actualiza antes de finales de enero de 2027.
Un ángulo más si usas agentes de codificación: la organización Langfuse publica plugins de observabilidad que trazan sesiones de Claude Code, Codex, Cursor, OpenCode y Pi a Langfuse, más un servidor MCP (el bloque env LANGFUSE_MCP_*) que expone la gestión de prompts a agentes. Es pronto, pero trazar sesiones de agentes al mismo sitio que las trazas de tu app es útil una vez que depuras ejecuciones de agente multi-paso.
Si quieres explorar más contenedores Docker para tu home server, incluyendo otras herramientas IA, mira los mejores 100+ contenedores Docker para home server. Langfuse también está listado con LiteLLM, OmniRoute y el stack de agentes en top AI GitHub repos.
Docs oficiales de Langfuse Guía de actualización v3 a v4

