# Metabase BI dashboards

Source: https://docs.quake.ai/resources/iac-templates/metabase
Markdown: https://docs.quake.ai/resources/iac-templates/metabase.md

---

# Metabase BI dashboards

This pattern composes Compute, Network, and Block Storage into a self-hosted business-intelligence host you run on infrastructure you control.

## What this template does

Provisions a single instance running [Metabase](https://www.metabase.com), an open-source BI tool (a self-hosted alternative to Looker or Power BI). Analysts build dashboards and ask questions in SQL or a visual query builder:

- Compute instance that runs Metabase in Docker, sized for the embedded H2 app database (2 vCPU and 2 GiB RAM)
- Private network, subnet, router, port, and security group; a floating IP for public access
- A block volume mounted at `/var/lib/docker`, so Metabase application data (saved questions, dashboards, users) lives on a volume you can grow rather than on the boot disk
- cloud-init installs Docker Engine and starts Metabase from a compose file on first boot

Metabase connects to analytical warehouses you already run, such as [self-managed PostgreSQL](/resources/iac-templates/self-managed-postgres) or [ClickHouse](/resources/iac-templates/clickhouse). You add warehouse connections from the Metabase admin UI after setup.

No credential ships with this template. You create the admin account on first visit, and warehouse passwords stay in the Metabase UI or environment on the instance, not in tfvars.

## Parameters

| Parameter | Description | Default |
| --- | --- | --- |
| `key_name` | SSH keypair name (must already exist) | No default |
| `flavor_name` | Instance size (embedded H2 mode runs on 2 vCPU / 2 GiB) | `s1a.small` |
| `image_name` | Operating system image | `Ubuntu-24.04` |
| `app_name` | Display name prefix for resources | `metabase` |
| `volume_size` | Block volume size in GiB, mounted at `/var/lib/docker` | `20` |
| `external_network` | External network for floating IP allocation | `PublicStatic` |
| `private_cidr` | CIDR for the private subnet | `10.40.0.0/24` |
| `editor_allowed_cidr` | CIDR allowed to reach the UI on port 3000 | `10.40.0.0/24` |
| `db_type` | App metadata store: `embedded` or `postgres` | `embedded` |
| `postgres_host` | PostgreSQL host (when `db_type` is `postgres`) | `""` |
| `postgres_db` | PostgreSQL database name (when `db_type` is `postgres`) | `metabase` |
| `postgres_user` | PostgreSQL user (when `db_type` is `postgres`) | `metabase` |

## UI access and security

The Metabase UI listens on port 3000 over plain HTTP. The security group restricts 3000 to `editor_allowed_cidr`, which defaults to the private network only, so the raw UI stays off the public internet. Reach it one of three ways:

- Put a reverse proxy (Caddy or Nginx) in front of Metabase and serve the UI over HTTPS on 443. Point the domain's DNS A record at the floating IP.
- Tunnel over SSH: `ssh -L 3000:localhost:3000 ubuntu@FLOATING_IP`, then open `http://localhost:3000`.
- Set `editor_allowed_cidr` to `YOUR_IP/32` to reach port 3000 directly from one address.

Ports 80 and 443 stay open for the reverse proxy you put in front; they carry no traffic until you add one.

## Application database

The `db_type` parameter selects where Metabase stores its own metadata (not your warehouse data):

- `embedded` (default): H2 file database on the data volume. No external service runs, which suits getting started and small teams.
- `postgres`: points Metabase at an external PostgreSQL database for app metadata. Set `postgres_host`, `postgres_db`, and `postgres_user`, then add `MB_DB_PASS` to `/opt/metabase/.env` on the instance and run `docker compose up -d`. The password stays out of tfvars and the repo.

## When to use this pattern

Run a self-service BI layer on a VM you operate. Metabase suits analyst dashboards, scheduled email reports, and SQL exploration against a warehouse you already host on Quake AI.

For a heavier BI stack with SQL Lab and richer charts, see [Apache Superset](/resources/iac-templates/superset). For the warehouse Metabase queries, see [self-managed PostgreSQL](/resources/iac-templates/self-managed-postgres).

## Estimated cost

<PricingCompanion
  components={[
    { kind: "template", slug: "metabase", required: true },
  ]}
/>

## Template source

<TemplateSource slug="metabase" />

<TemplateResourceMap template="metabase" format="opentofu" />

## Customize this pattern

- [Customize a template's image and flavor](/docs/automation/how-to/customize-template-image-flavor)
- [Add a block volume to a template](/docs/automation/how-to/add-volume-to-template)
- [Parameterize a template with a tfvars file](/docs/automation/how-to/parameterize-template-tfvars)

## See also

- [Apache Superset](/resources/iac-templates/superset)
- [self-managed PostgreSQL](/resources/iac-templates/self-managed-postgres)
- [Self-service BI stack](/resources/solutions/self-service-bi-stack)
