Metabase is the most popular open-source BI tool — it lets non-engineers explore data, build dashboards, and set up alerts with a friendly query builder, while still allowing raw SQL. Self-hosting it is common because BI tools sit close to sensitive data. The deployment is a single Java application, but there's one decision that determines whether your setup survives: where Metabase stores its own state.
Use an external application database
Metabase stores its configuration — questions, dashboards, users, permissions — in an application database. By default it uses an embedded H2 file database. H2 is fine for a five-minute trial and a documented footgun for anything real: it corrupts under load, can't be backed up cleanly while running, and lives on ephemeral container disk. Always configure an external Postgres (or MySQL) app database:
MB_DB_TYPE=postgres
MB_DB_HOST=your-managed-pg-host
MB_DB_PORT=5432
MB_DB_DBNAME=metabase
MB_DB_USER=metabase
MB_DB_PASS=...On PandaStack, provision a small managed PostgreSQL specifically as the Metabase app database and map these from the injected connection details. This is separate from the databases you'll analyze — don't mix the two.
Deploying the container
Metabase ships the metabase/metabase image and listens on port 3000. It's a pre-built image, so you deploy it directly with environment variables — no build step. Pin a version tag rather than latest so upgrades are deliberate (Metabase runs a one-way migration on its app DB at startup; downgrades are not supported).
JVM memory matters
Metabase is a JVM app, and the most common production incident is the container getting OOM-killed because the JVM heap wasn't bounded to fit the container's memory. Set the max heap explicitly to roughly 70-80% of the container's memory limit:
JAVA_OPTS=-Xmx2gPick a memory-appropriate compute tier and set -Xmx to leave headroom for non-heap memory. A 1 GB container with an unbounded heap will crash under a heavy dashboard; a 2 GB container with -Xmx1500m is far more stable.
| Container memory | Suggested -Xmx |
|---|---|
| 1 GB | ~700m |
| 2 GB | ~1500m |
| 4 GB | ~3g |
Connecting your data
After setup, add the databases you actually want to analyze — your PandaStack managed PostgreSQL, MySQL, or a data warehouse. Create a read-only user for Metabase; analysts should never be able to mutate production through a BI tool. Metabase also caches query results, which reduces load on the source database for popular dashboards.
Securing sharing
Metabase can publish dashboards via public links and signed embeds. Public sharing is convenient and risky — a public link is accessible to anyone who has it. For anything sensitive, use signed embedding with row-level parameters or keep dashboards behind login. Set MB_SITE_URL to your custom domain so public/embed links resolve correctly, and serve everything over HTTPS (automatic SSL on PandaStack custom domains).
Backups
Your Metabase state is in the application database, so back that up — a managed Postgres gives you scheduled backups automatically. The dashboards and questions are the asset; the Metabase container itself is disposable.
Go-live checklist
- External Postgres app database (never H2)
- Pinned image version
-Xmxset to fit the container; memory tier chosen- Read-only users for analyzed databases
MB_SITE_URL+ HTTPS; public sharing reviewed- App database backups enabled
References
- [Metabase running in Docker](https://www.metabase.com/docs/latest/installation-and-operation/running-metabase-on-docker)
- [Metabase application database](https://www.metabase.com/docs/latest/installation-and-operation/configuring-application-database)
- [Metabase environment variables](https://www.metabase.com/docs/latest/configuring-metabase/environment-variables)
- [Metabase embedding & public sharing](https://www.metabase.com/docs/latest/embedding/introduction)
Metabase deploys on PandaStack as a container service with a dedicated managed Postgres as its app database and your production databases connected read-only — all on memory-tier compute sized for the JVM. Start free at [dashboard.pandastack.io](https://dashboard.pandastack.io).