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...
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
---
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:
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:
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:
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:
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.
| Variable | Description | Default |
|---|---|---|
MB_DB_TYPE | Application DB type (postgres, mysql, h2) | h2 |
MB_DB_HOST | Application DB host | ā |
MB_DB_PORT | Application DB port | ā |
MB_DB_DBNAME | Application DB name | ā |
MB_DB_USER | Application DB username | ā |
MB_DB_PASS | Application DB password | ā |
MB_JETTY_PORT | Port Metabase listens on | 3000 |
MB_SITE_URL | Public URL of your Metabase instance | ā |
MB_EMBEDDING_SECRET_KEY | Secret key for signed embedding | ā |
MB_ANON_TRACKING_ENABLED | Disable usage tracking | true |
JAVA_TIMEZONE | JVM timezone | System 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:
A full Kubernetes deployment guide is covered separately in this series.
---
What Happens at Startup
Understanding Metabase's startup sequence helps diagnose issues:
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:
Schema sync does not copy data into Metabase. It only reads metadata.
---
Upgrading Metabase
To upgrade Metabase:
docker pull metabase/metabase:latestdocker stop metabasedocker rm metabaseMetabase 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
localhost inside the container refers to the container itself, not the host machine ā use host.docker.internal (Mac/Windows) or the host's IP addressStartup takes more than 3 minutes
"Application database is locked"
.db.lock file.Queries are slow
---
Next Steps
Once Metabase is running:
---
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.