Getting Started

How to Deploy Metabase in Under 10 Minutes

Metabase can be running and connected to a database in under 10 minutes using Docker. This guide covers the fastest path to a working Metabase instanc...

šŸ“…
šŸ“–7 min read

How to Deploy Metabase in Under 10 Minutes

Metabase can be running and connected to a database in under 10 minutes using Docker. This guide covers the fastest path to a working Metabase instance, the configuration decisions you'll need to make before going to production, and the most common deployment mistakes that cause problems later.

---

Prerequisites

  • Docker installed on your machine or server
  • A database you want to connect to (PostgreSQL, MySQL, SQLite, or any other supported source)
  • Optionally: a PostgreSQL database to use as Metabase's application database (required for production; not required for local evaluation)
  • ---

    Step 1: Run Metabase with Docker

    bash
    

    docker run -d \ -p 3000:3000 \ --name metabase \ metabase/metabase

    This pulls the latest Metabase image and starts it on port 3000. After 30–60 seconds, Metabase will be available at http://localhost:3000.

    The first time you visit, you'll be prompted to:

  • Create an admin account
  • Choose your preferred language
  • Connect your first database
  • Configure usage data sharing (optional)
  • That's it. Metabase is running.

    ---

    Step 2: Connect Your Database

    During setup, Metabase will prompt you to add a data source. You'll need:

  • Database type (PostgreSQL, MySQL, Snowflake, BigQuery, etc.)
  • Host and port
  • Database name
  • Username and password (use a read-only user for safety)
  • Metabase stores this connection configuration in its application database and uses it to execute queries at runtime. It does not copy or store your data.

    If you skip this step during setup, you can add a database connection later via Admin → Databases → Add Database.

    Recommended: Use a Read-Only Database User

    Create a dedicated read-only user for Metabase rather than using your application's primary database credentials:

    sql
    

    -- PostgreSQL example CREATE USER metabase_reader WITH PASSWORD 'your-password'; GRANT CONNECT ON DATABASE your_database 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;

    This ensures Metabase can read data but cannot modify it, and limits the blast radius if credentials are ever compromised.

    ---

    Step 3: Configure an Application Database (Production Only)

    By default, Metabase stores its own configuration — users, saved questions, dashboards, permissions — in an embedded H2 file database. This is fine for local evaluation but not suitable for production because:

  • H2 doesn't support concurrent writes reliably
  • The file is hard to back up and restore
  • It's not supported for production use by the Metabase team
  • For production, configure Metabase to use an external PostgreSQL database:

    bash
    

    docker run -d \ -p 3000:3000 \ --name metabase \ -e MB_DB_TYPE=postgres \ -e MB_DB_DBNAME=metabase \ -e MB_DB_PORT=5432 \ -e MB_DB_USER=metabase_app \ -e MB_DB_PASS=your-password \ -e MB_DB_HOST=your-postgres-host \ metabase/metabase

    Metabase will automatically create its schema on first run.

    ---

    Step 4: Verify the Setup

    Once Metabase is running and connected to a database, verify the setup by:

  • Navigating to the home screen and confirming your database appears under Browse Data
  • Creating a simple question: click New → Question, select your database, choose a table, and run it
  • Confirming the query returns results
  • If the query succeeds, your database connection is working correctly.

    ---

    Environment Variables Reference

    Metabase is configured primarily through environment variables, which makes it easy to manage configuration in Docker, Kubernetes, or any container orchestration platform.

    VariableDescriptionDefault
    MB_DB_TYPEApplication DB type (postgres, mysql, h2)h2
    MB_DB_HOSTApplication DB host—
    MB_DB_PORTApplication DB port—
    MB_DB_DBNAMEApplication DB name—
    MB_DB_USERApplication DB username—
    MB_DB_PASSApplication DB password—
    MB_JETTY_PORTPort Metabase listens on3000
    MB_SITE_URLPublic URL of your Metabase instance—
    MB_EMBEDDING_SECRET_KEYSecret key for signed embedding—
    MB_ANON_TRACKING_ENABLEDDisable usage trackingtrue
    JAVA_TIMEZONEJVM timezoneSystem default
    MB_SITE_URL is important to set correctly — it controls the base URL used in email links and embedding configurations.

    ---

    Common Deployment Patterns

    Local Development

    bash
    

    docker run -d -p 3000:3000 --name metabase metabase/metabase

    Simplest possible setup. Uses H2. Fine for trying things out.

    Docker Compose (Recommended for Most Teams)

    yaml
    

    version: '3.9' services: metabase: image: metabase/metabase:latest ports: - "3000:3000" environment: MB_DB_TYPE: postgres MB_DB_DBNAME: metabase MB_DB_PORT: 5432 MB_DB_USER: metabase_app MB_DB_PASS: ${METABASE_DB_PASSWORD} MB_DB_HOST: db MB_SITE_URL: https://analytics.yourapp.com depends_on: - db

    db: image: postgres:15 environment: POSTGRES_DB: metabase POSTGRES_USER: metabase_app POSTGRES_PASSWORD: ${METABASE_DB_PASSWORD} volumes: - metabase-db:/var/lib/postgresql/data

    volumes: metabase-db:

    This gives you a self-contained Metabase stack with a persistent PostgreSQL application database.

    Kubernetes

    For Kubernetes deployments, Metabase publishes a Helm chart. The key considerations are:

  • Use an external managed PostgreSQL instance (RDS, Cloud SQL) for the application database rather than a pod-backed database
  • Configure a PersistentVolumeClaim if using the H2 database (not recommended for production)
  • Set resource limits — Metabase's JVM typically needs at least 1.5GB of RAM for small deployments
  • A full Kubernetes deployment guide is covered separately in this series.

    ---

    What Happens at Startup

    Understanding Metabase's startup sequence helps diagnose issues:

  • JVM initialization — Metabase runs on the JVM (Java Virtual Machine). First startup takes 60–90 seconds as the JVM warms up.
  • Application DB migration — Metabase checks its application database schema and runs any pending migrations.
  • Database sync — Metabase connects to your configured data sources and syncs their schema (table names, column names, types). This runs on startup and on a recurring schedule.
  • Ready — The web server starts accepting connections on the configured port.
  • On subsequent starts, startup time drops to 20–40 seconds because migrations are already applied.

    Schema Sync

    Metabase periodically syncs the schema of your connected databases — by default, every hour. This sync:

  • Detects new and removed tables and columns
  • Updates data type information
  • Refreshes field value lists used by the query builder
  • Schema sync does not copy data into Metabase. It only reads metadata.

    ---

    Upgrading Metabase

    To upgrade Metabase:

  • Pull the new image: docker pull metabase/metabase:latest
  • Stop the current container: docker stop metabase
  • Remove the old container: docker rm metabase
  • Start with the new image using the same configuration
  • Metabase applies database migrations automatically on startup. Always back up your application database before upgrading.

    For production deployments, pin to a specific version tag (metabase/metabase:v0.50.0) rather than latest to control when upgrades happen.

    ---

    Common Issues and Fixes

    Metabase can't connect to the database

  • Verify the host, port, and credentials
  • Check that the database allows connections from the IP or container running Metabase
  • For Docker, remember that localhost inside the container refers to the container itself, not the host machine — use host.docker.internal (Mac/Windows) or the host's IP address
  • Startup takes more than 3 minutes

  • Usually a sign that the JVM doesn't have enough memory. Increase the container's memory limit to at least 2GB.
  • "Application database is locked"

  • Usually caused by a hard stop while H2 was writing. If using H2 for production (not recommended), delete the .db.lock file.
  • Queries are slow

  • Metabase query performance is bounded by your database performance. Slow queries usually indicate missing indexes, not a Metabase configuration issue.
  • Enable query caching in Metabase Admin → Performance for frequently-run dashboards.
  • ---

    Next Steps

    Once Metabase is running:

  • Create your first dashboard — connect a few saved questions and arrange them on a canvas
  • Set up user access — invite team members and configure permission groups
  • Configure embedding — if you're adding analytics to a product, see the Embedding guide in this series
  • Set up SSO — if your organization uses an identity provider, configure SAML or LDAP
  • ---

    Summary

    Deploying Metabase takes under 10 minutes with Docker. The default configuration using H2 is sufficient for local evaluation. Production deployments require an external PostgreSQL application database and should be configured via environment variables. Metabase is designed to be operated by developers — no dedicated data infrastructure engineer required.