Metabase
AstralAnalytics ships a docker-compose.yml that boots PostgreSQL and Metabase side-by-side. Use it to visualise the events table without writing a single line of code.
Boot
Services:
Service | Container | Port | Volume |
|---|---|---|---|
Postgres 15 |
| 5432 |
|
Metabase |
| 3000 |
|
Both join the metabase_net bridge network so Metabase resolves the database as db.
The shipped credentials are placeholders — change POSTGRES_PASSWORD and MB_DB_PASS before exposing the stack beyond localhost.
First-run setup
Open
http://localhost:3000.Follow the Metabase wizard for your admin account.
Add a database of type PostgreSQL pointing at the events database the master writes to:
Host:
dbfrom inside the Docker network, or your DB host externally.Database name:
metabase(or whatever you configured).Username / password: as set in
docker-compose.yml.
Metabase syncs and surfaces the
eventstable.
Dashboard building blocks
The events table is intentionally narrow — every dashboard reads created_at, type, player_uuid, and the payload JSONB.
Active players
Render as a time-series line chart.
Country breakdown
Render as a pie or world map.
Session length distribution
Render as a histogram. Buckets are 5-minute bands up to the first hour; anything longer falls in bucket 13.
Top commands
Render as a bar chart.
Mod presence
LATERAL jsonb_array_elements flattens the per-player mod arrays so each mod is one row.
LuckPerms promotion ladder
Render as a Sankey or simple table.
Tips
GIN index: the schema includes
CREATE INDEX … USING GIN (payload). Use the JSON containment operator@>(payload @> '{"country": "FR"}') to take advantage of it instead of casting.Filtering by server:
server_nameandserver_groupare top-level VARCHARs. Add them as table filters when you want per-shard or per-environment slices.Time-series with gaps: PostgreSQL's
generate_seriesis handy for filling missing days when the rawdate_truncquery has zero rows for a slot.Materialise common rollups: if a dashboard's query starts to feel slow, push it into a materialised view and refresh it on a cron. The
eventstable is append-only so rollups stay simple.