Self-host Supermetry

One Go binary, one PostgreSQL database.

Requirements

App
One Go binary with the dashboard embedded. No ClickHouse, Kafka or Node.
Database
PostgreSQL. CI runs 18; no lower minimum is documented.
Other
No Redis for one instance. Country GeoIP is bundled; MaxMind is optional.
Port
8787, bound to 127.0.0.1 in the Compose file.
Signup
Invite-only unless you open it.
SettingPurpose
SUPERMETRY_DATABASE_URLPostgreSQL URL.
SUPERMETRY_SECRET_KEYBase64 of 32+ random bytes. Lose it and stored TOTP and alert secrets break.
SUPERMETRY_BASE_URLPublic URL, HTTPS in production.

Docker Compose

Existing PostgreSQL
cp .env.example .env
# Set the three required values in .env
cd deploy
docker compose up -d --build
Bundled PostgreSQL
# Leave SUPERMETRY_DATABASE_URL unset
docker compose --profile bundled-db up -d --build

Config comes from ./.env or SUPERMETRY_ENV_FILE. Real environment variables win.

Build from source

Needs Go and Bun. Migrations run at startup.

Build and start
make build
export SUPERMETRY_DATABASE_URL='postgres://…'
export SUPERMETRY_SECRET_KEY="$(openssl rand -base64 32)"
export SUPERMETRY_BASE_URL='https://analytics.example.com'
bin/supermetry

Reverse proxy

Set trusted proxy IPs, overwrite X-Forwarded-For, use an HTTPS base URL.

Health

/healthz, /readyz, /metrics. Guard metrics with SUPERMETRY_METRICS_TOKEN or loopback.

Operations

TaskHow
Backupsupermetry backup --out FILE writes a mode-0600 archive (PostgreSQL dump plus manifest). Needs PostgreSQL client tools.
RestoreStop the app, run supermetry restore FILE --yes, restart. Newer-schema archives are refused.
UpgradeReplace the binary or image and restart. Migrations run; rollups rebuild in the background.
ReplayEnable per instance and per project. Files go in the data directory or S3.

Ready to install?

Read the docs