Metabase Business Intelligence Installation

Metabase is an open-source business intelligence platform that lets you connect to databases and build dashboards without writing SQL. This guide covers self-hosting Metabase on Linux using Docker, including database connections, the question builder, custom dashboards, user permissions, and performance tuning.

Prerequisites

  • Ubuntu 20.04+ / Debian 11+ or CentOS 8+ / Rocky Linux 8+
  • Docker and Docker Compose (recommended), or Java 11+
  • At least 2 GB RAM (4 GB recommended for production)
  • A database to analyze (PostgreSQL, MySQL, SQLite, etc.)
  • A dedicated PostgreSQL database for Metabase's own metadata (recommended for production)

Installing Metabase with Docker

Docker is the simplest way to run Metabase. Create a Docker Compose file for a production-ready setup:

# Create a directory for Metabase
mkdir -p /opt/metabase && cd /opt/metabase

# Create docker-compose.yml
cat > docker-compose.yml << 'EOF'
version: "3.9"
services:
  metabase-db:
    image: postgres:15-alpine
    container_name: metabase-db
    restart: unless-stopped
    environment:
      POSTGRES_DB: metabase
      POSTGRES_USER: metabase
      POSTGRES_PASSWORD: strongpassword
    volumes:
      - metabase-db-data:/var/lib/postgresql/data

  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: strongpassword
      MB_DB_HOST: metabase-db
      MB_SITE_URL: http://your-domain.com:3000
      JAVA_TIMEZONE: UTC
    depends_on:
      - metabase-db
    volumes:
      - metabase-data:/metabase-data

volumes:
  metabase-db-data:
  metabase-data:
EOF

# Start Metabase
docker compose up -d

# Check logs during startup (first start takes 1-2 minutes)
docker compose logs -f metabase

Installing Metabase without Docker

For a bare-metal installation using Java:

# Install Java 11
# Ubuntu/Debian:
sudo apt-get update && sudo apt-get install -y openjdk-11-jre-headless

# CentOS/Rocky:
sudo dnf install -y java-11-openjdk-headless

# Create Metabase user and directory
sudo useradd -r -m -d /opt/metabase metabase
sudo mkdir -p /opt/metabase
cd /opt/metabase

# Download Metabase JAR
sudo curl -o metabase.jar https://downloads.metabase.com/latest/metabase.jar
sudo chown metabase:metabase metabase.jar

# Create environment file
sudo cat > /opt/metabase/metabase.env << 'EOF'
MB_DB_TYPE=postgres
MB_DB_DBNAME=metabase
MB_DB_PORT=5432
MB_DB_USER=metabase
MB_DB_PASS=strongpassword
MB_DB_HOST=localhost
MB_SITE_URL=http://your-domain.com:3000
JAVA_TIMEZONE=UTC
EOF

# Create systemd service
sudo cat > /etc/systemd/system/metabase.service << 'EOF'
[Unit]
Description=Metabase BI Server
After=network.target postgresql.service

[Service]
User=metabase
WorkingDirectory=/opt/metabase
EnvironmentFile=/opt/metabase/metabase.env
ExecStart=/usr/bin/java -jar /opt/metabase/metabase.jar
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now metabase
sudo systemctl status metabase

Initial Setup and Database Connection

After starting, access Metabase at http://your-server:3000. The setup wizard walks you through:

  1. Create your admin account (name, email, password)
  2. Tell Metabase about your organization
  3. Connect your first database

To add a database connection later via the Admin Panel:

  1. Go to Settings (gear icon) → AdminDatabases
  2. Click Add database
  3. Select your database type and fill in connection details
  4. Click Save

For PostgreSQL, the connection test verifies credentials and network access. If you're connecting to a database on the host machine from Docker, use the host IP or host.docker.internal.

# Allow Metabase container to reach host PostgreSQL
# On host, edit pg_hba.conf to allow the Docker subnet
sudo nano /etc/postgresql/15/main/pg_hba.conf
# Add: host  mydb  myuser  172.17.0.0/16  md5

# Reload PostgreSQL
sudo systemctl reload postgresql

Building Questions and Visualizations

Metabase's Question Builder lets non-technical users query data without SQL:

  1. Click NewQuestion
  2. Choose your data source (table or model)
  3. Add Filters (e.g., date range, category)
  4. Add Summaries (e.g., count by category, sum by month)
  5. Select a visualization type (bar chart, line, map, etc.)
  6. Click Save and name your question

For SQL power users, use the Native Query Editor:

  1. Click NewSQL query
  2. Select your database
  3. Write your SQL with optional template variables:
-- Template variable for date filtering
SELECT
    date_trunc('month', created_at) AS month,
    count(*) AS new_users
FROM users
WHERE created_at >= {{start_date}}
  AND created_at < {{end_date}}
GROUP BY 1
ORDER BY 1;

Variables like {{start_date}} become filter widgets on the dashboard.

Creating Dashboards

Dashboards combine multiple questions into a single view:

  1. Click NewDashboard
  2. Name your dashboard
  3. Click Add a question and search for saved questions
  4. Drag and resize cards to arrange the layout
  5. Click Add a filter to link a dashboard filter to multiple questions
  6. Click Save

To set auto-refresh for live dashboards:

  • Click the clock icon in the top-right
  • Select refresh interval (1 min, 5 min, etc.)

User Permissions and Groups

Metabase uses groups to control data access:

Admin Panel → People → Groups

Default groups:

  • Administrators - full access
  • All Users - baseline permissions (restrict this group)

Create a custom group:

  1. Go to AdminPeopleGroupsCreate a group
  2. Name the group (e.g., "Finance Team")
  3. Add users to the group
  4. Go to AdminPermissionsData
  5. Set database/schema/table access per group:
    • Unrestricted - can query any table
    • Granular - choose table-by-table
    • No self-service - can only see saved questions

For collection permissions (who sees which dashboards):

  • AdminPermissionsCollections

Embedding and Sharing

Public links - anyone with the link can view (no login required):

  • Open a question or dashboard → click Share → enable public link

Signed embedding (embed in your app with JWT):

# Generate a signing key
openssl rand -hex 32

Set this key in AdminEmbeddingEmbedding secret key.

In your application, generate a signed token:

import jwt, time

METABASE_SITE_URL = "http://your-domain.com:3000"
METABASE_SECRET_KEY = "your-signing-key"

payload = {
    "resource": {"dashboard": 1},  # dashboard ID
    "params": {},
    "exp": round(time.time()) + (60 * 10)  # 10 min expiry
}

token = jwt.encode(payload, METABASE_SECRET_KEY, algorithm="HS256")
iframe_url = f"{METABASE_SITE_URL}/embed/dashboard/{token}#bordered=true&titled=true"

Performance Tuning

# Increase JVM heap for Metabase (Docker)
# Edit docker-compose.yml environment section:
environment:
  JAVA_OPTS: "-Xmx2g -Xms512m"

# Enable question caching in Admin → Caching
# Set minimum query time to cache (e.g., 60 seconds)
# Cached results are stored for a configurable TTL

# For large datasets, create database indexes on commonly filtered columns
# Example for PostgreSQL:
psql -U myuser -d mydb << 'SQL'
CREATE INDEX CONCURRENTLY idx_orders_created_at ON orders(created_at);
CREATE INDEX CONCURRENTLY idx_orders_status ON orders(status);
SQL

# Monitor Metabase logs for slow queries
docker compose logs metabase | grep -i "slow\|timeout"

Enable query caching in AdminPerformanceCaching to avoid re-running expensive queries on every dashboard load.

Troubleshooting

Metabase won't start:

docker compose logs metabase | tail -50
# Look for database connection errors or Java heap errors

"Can't connect to database" error:

# Test connectivity from Metabase container
docker exec -it metabase bash
# Then test with nc or curl
nc -zv your-db-host 5432

Slow dashboard loading:

  • Enable caching for slow questions
  • Add database indexes on filter columns
  • Check if the application database (Metabase's own DB) is on slow storage

Out of memory errors:

# Increase heap size
JAVA_OPTS="-Xmx4g" docker compose up -d metabase

SMTP/email not working:

  • Go to AdminEmail and test the SMTP connection
  • Ensure port 587 or 465 is not blocked by firewall

Reset admin password:

docker exec -it metabase java -jar /app/metabase.jar reset-password [email protected]

Conclusion

Metabase provides a powerful self-hosted BI platform that makes data exploration accessible to technical and non-technical users alike. With Docker deployment, PostgreSQL as the application database, and careful permission setup, you can have a production-ready analytics platform running on your VPS. Enable query caching and add appropriate database indexes to keep dashboards fast as your data grows.