DEV Community

Royce
Royce

Posted on • Originally published at ossalt.com

Self-Hosting Guide: Deploy Metabase for Business Intelligence

Self-Hosting Guide: Deploy Metabase for Business Intelligence

Metabase is the most popular open source BI tool — it lets non-technical users explore data, build dashboards, and share insights without writing SQL. Self-hosting gives you unlimited users and dashboards for free.

Requirements

  • VPS with 2 GB RAM minimum (4 GB recommended)
  • Docker and Docker Compose
  • Domain name (e.g., bi.yourdomain.com)
  • 10+ GB disk
  • A database to analyze (PostgreSQL, MySQL, etc.)

Step 1: Create Docker Compose

# docker-compose.yml
services:
  metabase:
    image: metabase/metabase:latest
    container_name: metabase
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      - MB_DB_TYPE=postgres
      - MB_DB_DBNAME=metabase
      - MB_DB_PORT=5432
      - MB_DB_USER=metabase
      - MB_DB_PASS=your-strong-password
      - MB_DB_HOST=db
      - MB_SITE_URL=https://bi.yourdomain.com
      - MB_ENCRYPTION_SECRET_KEY=your-random-32-char-key
    depends_on:
      - db

  db:
    image: postgres:16-alpine
    container_name: metabase-db
    restart: unless-stopped
    volumes:
      - postgres_data:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=metabase
      - POSTGRES_USER=metabase
      - POSTGRES_PASSWORD=your-strong-password

volumes:
  postgres_data:
Enter fullscreen mode Exit fullscreen mode

Note: This PostgreSQL is for Metabase's own data (dashboards, users, settings). Your business data lives in separate databases that you'll connect in Step 6.

Step 2: Generate Encryption Key

openssl rand -hex 16
Enter fullscreen mode Exit fullscreen mode

This encrypts database credentials stored in Metabase.

Step 3: Start Metabase

docker compose up -d
Enter fullscreen mode Exit fullscreen mode

First boot takes 1-2 minutes to initialize.

Step 4: Reverse Proxy (Caddy)

# /etc/caddy/Caddyfile
bi.yourdomain.com {
    reverse_proxy localhost:3000
}
Enter fullscreen mode Exit fullscreen mode
sudo systemctl restart caddy
Enter fullscreen mode Exit fullscreen mode

Step 5: Initial Setup Wizard

  1. Open https://bi.yourdomain.com
  2. Select your language
  3. Create admin account
  4. Connect your first database (can skip and add later)
  5. Choose usage tracking preference

Step 6: Connect Your Data Sources

Go to AdminDatabasesAdd database:

Database Connection String
PostgreSQL host:5432/dbname
MySQL host:3306/dbname
MongoDB mongodb://host:27017/dbname
SQLite /path/to/database.db
BigQuery Service account JSON
Snowflake Account + credentials
Redshift host:5439/dbname

Tip: Create a read-only database user for Metabase:

CREATE USER metabase_reader WITH PASSWORD 'read-only-password';
GRANT CONNECT ON DATABASE myapp TO metabase_reader;
GRANT USAGE ON SCHEMA public TO metabase_reader;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO metabase_reader;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO metabase_reader;
Enter fullscreen mode Exit fullscreen mode

Step 7: Build Your First Dashboard

Create a question (query):

  1. Click NewQuestion
  2. Pick your database and table
  3. Use the visual query builder or write SQL
  4. Save the question

Build a dashboard:

  1. Click NewDashboard
  2. Add saved questions as cards
  3. Add filters (date range, category, etc.)
  4. Arrange and resize cards
  5. Save and share

Common dashboard patterns:

Dashboard Metrics
Revenue MRR, churn rate, LTV, new subscriptions
Product DAU/MAU, feature usage, retention cohorts
Support Ticket volume, response time, CSAT scores
Marketing Traffic, conversion rate, CAC, channel performance

Step 8: Configure SMTP for Alerts

AdminSettingsEmail:

Setting Value
SMTP Host smtp.resend.com
SMTP Port 587
SMTP Security TLS
SMTP Username resend
SMTP Password re_your_api_key
From Address bi@yourdomain.com

Enables:

  • Scheduled dashboard emails (daily/weekly reports)
  • Alert notifications (when metrics cross thresholds)
  • User invitation emails

Step 9: Set Up Alerts

  1. Open a question/chart
  2. Click the bell icon → Create alert
  3. Choose condition: "When results go above/below X"
  4. Set recipients and frequency
  5. Alerts fire automatically when conditions are met

Step 10: Embedding (Optional)

Embed Metabase dashboards in your app:

// Generate signed embed URL (server-side)
const jwt = require('jsonwebtoken');

const METABASE_SITE_URL = 'https://bi.yourdomain.com';
const METABASE_SECRET_KEY = 'your-embedding-secret-key';

const payload = {
  resource: { dashboard: 1 },
  params: {},
  exp: Math.round(Date.now() / 1000) + (10 * 60), // 10 min expiration
};

const token = jwt.sign(payload, METABASE_SECRET_KEY);
const embedUrl = `${METABASE_SITE_URL}/embed/dashboard/${token}`;
Enter fullscreen mode Exit fullscreen mode
<iframe
  src="https://bi.yourdomain.com/embed/dashboard/TOKEN"
  width="100%"
  height="600"
  frameborder="0"
></iframe>
Enter fullscreen mode Exit fullscreen mode

Enable embedding in AdminSettingsEmbedding.

Production Hardening

Environment tuning:

environment:
  - JAVA_OPTS=-Xmx2g  # Increase for large datasets
  - MB_JETTY_MAXTHREADS=100
  - MB_ASYNC_QUERY_THREAD_POOL_SIZE=10
Enter fullscreen mode Exit fullscreen mode

Backups:

# Database backup (daily cron)
docker exec metabase-db pg_dump -U metabase metabase > /backups/metabase-$(date +%Y%m%d).sql
Enter fullscreen mode Exit fullscreen mode

Updates:

docker compose pull
docker compose up -d
Enter fullscreen mode Exit fullscreen mode

Security:

  • Use read-only database users
  • Enable SSL for all database connections
  • Restrict Admin access to specific users
  • Set session timeout in Admin settings

Resource Usage

Users RAM CPU Disk
1-10 2 GB 2 cores 10 GB
10-50 4 GB 4 cores 15 GB
50-200 8 GB 8 cores 30 GB

VPS Recommendations

Provider Spec (20 users) Price
Hetzner 4 vCPU, 8 GB RAM €8/month
DigitalOcean 2 vCPU, 4 GB RAM $24/month
Linode 2 vCPU, 4 GB RAM $24/month

Compare BI tools on OSSAlt — features, data sources, and self-hosting options side by side.

Top comments (0)