Why self-host your BI dashboards
Hosted BI tools are convenient until the per-seat bill arrives — and until you realise your product, revenue and customer data are being copied into a third-party SaaS priced in USD. Metabase flips that: it is open source (AGPL), self-hostable, and connects to a database you already own. Run it on a VPS behind your own domain and your analytics layer never leaves your server. You pay a fixed monthly cost for the VPS, not a growing per-user subscription, and your data stays on infrastructure you control — which for a Moroccan team also means data sovereignty, not a datacenter on another continent.
What Metabase gives you
- A visual query builder so non-technical users create charts and questions by clicking — with a full SQL editor for analysts.
- Interactive dashboards with filters, drill-through and scheduled refresh.
- Connectors for 20+ databases: PostgreSQL, MySQL/MariaDB, SQL Server, ClickHouse, BigQuery, Redshift, Snowflake and more.
- Scheduled subscriptions and threshold alerts delivered to email or Slack.
- Group- and collection-level permissions plus row/column controls so each team sees only its own data.
- Embedded analytics to drop signed, filtered dashboards into your own app.
- AGPL open source — no per-seat fee, its own state stored in a Postgres database you own.
Requirements
A VPS with Ubuntu 22.04 (or Debian 12) and Docker installed. Metabase runs on the JVM, so give it room: 2 GB RAM is the realistic minimum and 4 GB is comfortable for a small team. The deployment is two containers — Metabase itself and a companion postgres:16 that stores Metabase's own metadata (users, dashboards, saved questions). No domain is strictly required — Metabase answers on port 3000 via your server's IP — but you will want a reverse proxy for HTTPS in production.
Deploy Metabase on your VPS
Create a docker-compose stack
Metabase should store its own state in a real database, not the default embedded H2 file. Create a docker-compose.yml with two services: metabase/metabase:v0.62.3.6 and a companion postgres:16. Wire Metabase to Postgres with MB_DB_TYPE=postgres, MB_DB_HOST=metabase-db, MB_DB_DBNAME=metabaseappdb, MB_DB_PORT=5432, MB_DB_USER=metabase and a strong MB_DB_PASS. Use the same password for the Postgres container's POSTGRES_PASSWORD, mount a named volume for /var/lib/postgresql/data, and set restart: unless-stopped on both.
Bring it up and wait for boot
Run docker compose up -d. On first start Metabase runs its database migrations against Postgres, which takes 60–120 seconds on a small VPS — this is normal. Poll readiness with curl -f http://localhost:3000/api/health; once it returns {"status":"ok"} the app is ready. The compose stack gates Metabase on the Postgres healthcheck so the app never starts before its database is up.
Finish the setup wizard
Open http://<your-server-ip>:3000. Metabase redirects to the setup wizard: create the admin account, then connect the database you actually want to analyse — typically your application's PostgreSQL or MySQL, ideally a read replica so analytics queries never hit your production primary. Metabase scans the schema and your tables are query-ready in seconds.
Build a dashboard
Create a couple of questions with the visual query builder (a count over time, a breakdown by category), save them into a collection, and pin them onto a dashboard with a date filter. Switch any question to the native SQL editor when you need full control. Set up an email or Slack subscription to have the dashboard delivered on a schedule.
Add HTTPS and lock it down
Put Metabase behind a reverse proxy for a real domain and a certificate. With Caddy: apt install caddy, then a /etc/caddy/Caddyfile containing bi.yourdomain.com { reverse_proxy localhost:3000 } and systemctl reload caddy for an automatic Let's Encrypt cert. Point the DNS A record for bi.yourdomain.com at your VPS first, restrict port 3000 with ufw allow from <proxy> to any port 3000, and set a strong admin password — anyone who can log in can query every connected database.
Logging in for the first time
Open the address right after the installation: Metabase shows a welcome screen, then “Let's get started”, and creates an account for you from your name, your e-mail and the password you choose — this first account is automatically an administrator.
Point Metabase at a read replica, not your primary
Analytics queries can be heavy. Connect Metabase to a read replica or a dedicated reporting database rather than your production primary, so a slow dashboard query never slows down your live application. On a single VPS you can run a lightweight replica in its own container on the same private Docker network — Metabase reaches it by service name and your primary stays untouched.