Auto-hospeda Metabase con Postgres
Sigue esto en tu propio servidor. Empieza gratis, sin tarjeta
La mayoría de las herramientas de BI cobran por asiento, lo que convierte “que todo el equipo vea el dashboard” en un gasto que crece cada vez que alguien nuevo necesita acceso. Metabase es analítica autoservicio de código abierto que hace el trabajo central, conectar una base de datos, construir gráficos y dashboards, dejar que gente no técnica haga preguntas sin escribir SQL, sin factura por asiento una vez que corre en tu propio servidor. Esta guía lo monta con su propia base de datos Postgres para guardar dashboards y preguntas, detrás de Caddy para el HTTPS, y luego muestra el atajo en un clic.
Al final tendrás Metabase corriendo en tu propio dominio, conectado a su propio almacén de metadatos, listo para apuntar a cualquier base de datos o warehouse que de verdad quieras analizar.
Lo que necesitas
- Un servidor. Metabase en sí es una app de JVM con requisitos modestos para un equipo pequeño; un Hetzner CX23 (2 vCPU, 4 GB de RAM, 40 GB NVMe) a €5.99/mes sin IVA corre Metabase y su propio Postgres cómodamente. Un uso más pesado de dashboards o resultados grandes quieren más memoria; un CX33 (4 vCPU, 8 GB, €8.99/mes) es el siguiente paso.
- Un dominio o subdominio con un registro DNS A apuntando al servidor (esta guía usa
bi.example.com). - Acceso SSH y unos 15 minutos.
- Opcionalmente, la base de datos o warehouse que de verdad quieres que Metabase consulte. Esta guía solo configura la base de datos propia de la aplicación Metabase; conectar tu fuente de datos real se hace desde dentro de la app después del primer inicio de sesión.
Paso 1: aprovisiona el servidor y apunta el DNS
bi.example.com. A 203.0.113.40
ssh root@203.0.113.40
apt update && apt upgrade -y
Paso 2: instala Docker
curl -fsSL https://get.docker.com | sh
systemctl enable --now docker
docker --version
docker compose version
Paso 3: escribe el archivo de entorno
mkdir -p /opt/metabase && cd /opt/metabase
DB_NAME=metabase
DB_USER=metabase
DB_PASSWORD=change-this-to-a-random-string
Esta contraseña es para la propia base de datos Postgres de Metabase, la que guarda dashboards, preguntas guardadas y cuentas de usuario, no la fuente de datos que eventualmente conectarás.
Paso 4: escribe el archivo Docker Compose
Esta guía usa la versión estable actual, Metabase v0.64.3.4, fijada explícitamente en vez de latest para que una versión del upstream sin relación no pueda cambiar tu stack por debajo de ti:
services:
caddy:
image: caddy:2
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy-data:/data
- caddy-config:/config
metabase:
image: metabase/metabase:v0.64.3.4
restart: unless-stopped
environment:
MB_DB_TYPE: postgres
MB_DB_HOST: db
MB_DB_PORT: "5432"
MB_DB_DBNAME: ${DB_NAME}
MB_DB_USER: ${DB_USER}
MB_DB_PASS: ${DB_PASSWORD}
depends_on:
db:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:3000/api/health || exit 1"]
interval: 10s
timeout: 5s
retries: 10
db:
image: postgres:18-alpine
restart: unless-stopped
environment:
POSTGRES_DB: ${DB_NAME}
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- metabase-db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USER} -d ${DB_NAME}"]
interval: 5s
timeout: 5s
retries: 5
volumes:
metabase-db-data:
caddy-data:
caddy-config:
MB_DB_TYPE, MB_DB_HOST, MB_DB_PORT, MB_DB_DBNAME, MB_DB_USER y MB_DB_PASS son las variables de entorno exactas que los documentos de Metabase especifican para apuntarlo a una base de datos Postgres externa en vez de la base H2 integrada a la que recurre sin ellas, que no está pensada para más que una prueba rápida. Valida el archivo:
docker compose config
Paso 5: escribe el Caddyfile
bi.example.com {
reverse_proxy metabase:3000
}
Paso 6: levanta el stack
docker compose up -d
docker compose ps
Deberías ver caddy, metabase y db todos como running, con metabase reportando healthy una vez termina su propio arranque, lo que toma uno o dos minutos la primera vez ya que está inicializando su esquema de metadatos en Postgres. Revisa los logs si tarda más:
docker compose logs -f metabase
Visita https://bi.example.com; deberías llegar al asistente de configuración inicial de Metabase con un certificado HTTPS válido.
Paso 7: termina la configuración y conecta una fuente de datos real
El asistente de configuración crea tu cuenta admin directamente, sin contraseña por defecto que cambiar después como funcionan algunas apps autoalojadas. Una vez dentro, agrega la base de datos que de verdad quieres analizar desde Settings → Admin settings → Databases → Add a database. Esta es una conexión separada del contenedor Postgres del paso 4, que solo guarda las propias preguntas y dashboards de Metabase, no tus datos.
Paso 8: respalda la base de datos de metadatos
Dashboards, preguntas guardadas y cuentas de usuario viven en el contenedor Postgres del paso 4, no en las fuentes de datos que conectas. Respáldalo en un horario:
docker compose exec -T db pg_dump -U ${DB_USER} ${DB_NAME} | gzip > /opt/metabase/backups/metabase-$(date +%F).sql.gz
Copia el archivo fuera del servidor con una tarea cron. Restaurarlo después de una instalación nueva te devuelve tus dashboards y preguntas; tus fuentes de datos reales no se ven afectadas en ningún caso ya que no se guardan aquí.
Paso 9: actualizaciones
docker compose pull metabase
docker compose up -d metabase
Revisa las notas de versión propias de Metabase antes de saltar varias versiones mayores; corre sus propias migraciones de base de datos automáticamente al arrancar, y un respaldo del paso 8 de antemano es un seguro barato contra que algo salga mal.
El atajo: hazlo con Railyard
Todo lo anterior, los dos contenedores, el archivo de entorno, el proxy inverso, es lo que la plantilla de stack Metabase + Postgres de Railyard configura por ti. Elígela en el catálogo de plantillas: https://app.railyard.run/deploy?stack=metabase-postgres. Railyard aprovisiona Metabase y una instancia de Postgres dedicada juntas y conecta la relación automáticamente, así que no hay nada que conectar a mano. La misma separación del paso 7 sigue aplicando: esta instancia de Postgres es el almacén de metadatos propio de Metabase, y tu warehouse real o base de datos de producción se conecta por separado desde Settings → Databases después del primer inicio de sesión. De ahí en adelante, los respaldos de base de datos corren en un horario y se restauran en un clic.
Solución de problemas
El HTTPS nunca se emite. El DNS todavía no apunta al servidor. dig +short bi.example.com debería devolver la IP del servidor.
El contenedor de Metabase reinicia en bucle justo después de arrancar. Revisa primero docker compose logs metabase buscando un error de conexión a la base de datos; la causa más común es que MB_DB_PASS no coincida con lo que de verdad está en el entorno del contenedor db, usualmente porque .env no estaba presente o bien nombrado cuando el stack arrancó por primera vez.
El primer inicio de sesión tarda mucho, o expira en el navegador. Metabase corre sus propias migraciones de esquema contra Postgres en el primer arranque, lo que puede tomar uno o dos minutos según la velocidad del servidor. Revisa que docker compose logs metabase siga avanzando en vez de asumir que algo está roto.
Los dashboards cargan lento. Esto suele ser más la fuente de datos que Metabase consulta que Metabase mismo; consultas grandes sin índices contra una base de producción serán lentas sin importar quién las pida. Revisa el rendimiento de las consultas contra la base conectada real, y considera una réplica de lectura para carga de reportes pesada si la base de producción misma está bajo presión.
Falta de memoria en un servidor pequeño. La JVM sobre la que corre Metabase tiene necesidades reales de memoria base; un CX23 alcanza para un equipo pequeño, pero si también corres otros contenedores en la misma máquina, docker compose ps mostrando metabase como exited combinado con dmesg | grep -i "out of memory" lo confirma, y la solución es más memoria o menos cosas compartiendo este servidor.
Preguntas frecuentes
¿Puedo conectar más de una base de datos? Sí, cualquier cantidad, cada una configurada por separado desde Settings → Databases; Metabase mismo solo necesita la única instancia de Postgres de esta guía para su propio almacenamiento sin importar a cuántas fuentes la conectes.
¿Metabase necesita acceso a internet para funcionar? No, una vez instalado corre completamente contra su propia base de datos Postgres y las fuentes de datos que conectes, sin dependencia saliente para la operación diaria.
¿Cuál es la diferencia entre la versión de código abierto y las de pago? La edición de código abierto cubre dashboards, preguntas, alertas y el constructor de consultas que esta guía configura; los planes de pago de Metabase agregan cosas como SSO, logs de auditoría y marca blanca dirigidas a organizaciones más grandes, que esta guía no necesita.
¿La gente no técnica realmente puede usar esto sin aprender SQL? Esa es la función específica alrededor de la cual está construido Metabase: su constructor de preguntas deja que alguien filtre, agrupe y grafique datos mediante una interfaz visual, con SQL disponible como opción para quien lo quiera en vez de un requisito.
¿Cómo es esto más barato que una herramienta de BI alojada? El costo de una herramienta alojada por asiento crece con cuánta gente en la empresa necesita un dashboard; un CX23 a unos seis euros al mes cuesta igual ya sean tres o treinta personas quienes lo revisen.
¿Puedo correr Metabase sin Docker? Sí, también se distribuye como un archivo JAR plano que corres directamente con una JVM, lo que algunos equipos prefieren en un servidor que ya gestiona despliegues de Java; la imagen Docker es el camino que esta guía y la plantilla de Railyard usan ambas, ya que mantiene la versión de la JVM y las dependencias fijadas junto a la app misma en vez de depender de lo que ya esté instalado en el host.
Metabase le da a un equipo dashboards de autoservicio sin convertir “una persona más necesita acceso” en una conversación de facturación. La configuración aquí cabe en dos contenedores, un archivo de entorno y un proxy inverso; de ahí en adelante es el mismo constructor de preguntas y los mismos dashboards, corriendo en un servidor con costo mensual fijo en vez de uno que crece con la plantilla de personal.
Por qué eligen Railyard para esto
- Tu propia cuenta en la nube. Despliega en DigitalOcean, Hetzner, Vultr, AWS, OVHcloud, o cualquier servidor Linux por SSH, facturado directamente por tu proveedor, sin márgenes adicionales.
- Un precio fijo por equipo. El plan Free es gratis para siempre: un servidor más un servidor de base de datos, tres apps, sin tarjeta. Pro cuesta $19 al mes por hasta cinco servidores y apps ilimitadas. Team cuesta $49 al mes con servidores ilimitados. Sin cargos por app, por despliegue, por asiento ni por gigabyte.
- Plantillas de un clic. Despliega apps de código abierto, como bases de datos, analítica y herramientas de desarrollo, en tu propio servidor con un clic.
- Bases de datos administradas. Postgres, MySQL y Redis, con copias de seguridad programadas y verificadas por restauración, y recuperación a un punto en el tiempo.
- Despliegue con git push. Despliega desde GitHub, GitLab o la CLI, con HTTPS automático y lanzamientos sin tiempo de inactividad.