Grafana with PostgreSQL
Grafana with a real database — for multi-user production.
Grafana paired with a dedicated PostgreSQL backend in one Pier stack. The PostgreSQL-backed deployment is what Grafana recommends for production — multi-user, HA-friendly, and avoids the SQLite write-lock issues that plague Grafana under load with multiple concurrent editors.
Deploy with Pier
- 1 Open the Pier dashboard and click Add service.
- 2 Pick Grafana with PostgreSQL from the template list.
- 3 Choose the version, set a service name, and Pier provisions the container, storage, and ports automatically.
- 4 Attach a domain if you want HTTPS. Traefik auto-provisions the Let's Encrypt certificate.
What is Grafana with PostgreSQL?
This template ships Grafana — the de-facto observability dashboard platform — wired to a dedicated PostgreSQL backend for its internal state (users, dashboards, organizations, alerts, annotations). Grafana documents PostgreSQL (or MySQL) as the recommended backend for any multi-user or production deployment; SQLite is fine only for single-admin homelab use.
The two services come up together in one Compose stack with the env vars already set so Grafana finds Postgres on the internal Docker network. No manual GF_DATABASE_* configuration. You log in and use Grafana exactly as you would the standalone template — the database backend is invisible.
How Pier deploys it
Pier uses the official grafana/grafana image and postgres:17-alpine
for the backend. Grafana on port 3000 internally behind Traefik.
PostgreSQL stays on the internal Docker network (not exposed). Each
service has its own data volume — /var/lib/grafana for Grafana plugins
and provisioning, /var/lib/postgresql/data for Postgres data.
Default admin user is admin with a Pier-generated password (shown on
the service page). Change it on first login.
For HTTPS, attach a custom domain to the Grafana service in Pier — Traefik handles TLS termination and proxies to port 3000.
When NOT to use this template
If you’re a single user with a homelab and don’t expect concurrent
editing, the standalone grafana template is simpler. If you already
have a managed PostgreSQL (Pier or RDS or anywhere), use the standalone
Grafana template and point it at the existing Postgres via env vars.
For Grafana-as-a-service without ops overhead, Grafana Cloud’s free
tier is worth considering. This template is the right answer for “I
want production Grafana on my own VPS and I don’t want to wire two
services together by hand.”
Key features
Production-ready persistence
Grafana's user database — dashboards, organizations, users, sessions, annotations — lives in PostgreSQL instead of SQLite. Handles concurrent writes cleanly.
Pre-wired env
Pier sets GF_DATABASE_TYPE=postgres, host/user/password env vars, and connection settings — Grafana boots straight into Postgres without manual provisioning.
Same Grafana UI
Dashboards, panels, alerting, plugins — identical to the SQLite Grafana. Only the backing store differs.
All Grafana plugins
Datasources (Prometheus, InfluxDB, ES, ClickHouse, MySQL, Postgres, Loki, Tempo, Mimir), panel plugins, app plugins — everything compatible.
Backup / restore via Postgres
pg_dump backs up the entire Grafana state. Restore is pg_restore on a fresh stack. Much easier than juggling Grafana SQLite + provisioning files.
Multi-org / team scale
Concurrent editing by many users on many dashboards works without write-lock contention.
Use cases
Multi-user analytics team
A handful or dozens of analysts editing dashboards concurrently. PostgreSQL avoids the SQLite write-lock errors that surface under team load.
HA / disaster-recovery scenarios
PG backups + standby replicas give you point-in-time recovery and warm-standby options that SQLite can't.
Large dashboard / annotation volume
Many thousands of dashboards and high-write annotation streams (e.g. CI alerts, deploy markers) — Postgres scales well past where SQLite degrades.
Centralized observability hub
One Grafana instance serving 100s of users across many teams — exactly the deployment Grafana recommends Postgres for.
Code examples
Configuration → Data sources → PostgreSQL
Host: postgres:5432
Database: grafana
User: grafana
Password: (from Pier env)
TLS: disabled (internal Docker network) Configuration → Data sources → Prometheus
URL: https://prometheus.example.com
Auth: Bearer Token or Basic curl -H "Authorization: Bearer $API_KEY" \
https://grafana.example.com/api/dashboards/uid/abc123 > dashboard.json # /etc/grafana/provisioning/dashboards/default.yaml
apiVersion: 1
providers:
- name: default
folder: ""
type: file
options:
path: /var/lib/grafana/dashboards How it compares
| vs Grafana with SQLite (default standalone) | SQLite Grafana is simpler and fine for single-admin or small homelab use. Postgres-backed Grafana is required when multiple users edit concurrently, or for any HA setup. |
| vs Grafana Cloud | Grafana Cloud is hosted, includes free tier, autoscales. Self-host on Pier is free for data plane and gives you control. Choose by team budget and ops appetite. |
| vs Metabase / Superset | Metabase and Superset target BI analysts more than ops dashboards. Grafana is the default for ops/observability; the others for embedded analytics. |
Frequently asked questions
What's wrong with SQLite Grafana?
Can I migrate from SQLite Grafana to Postgres Grafana?
Does this PostgreSQL also serve as a datasource I can query?
How big can it scale?
Plugin compatibility?
Backup strategy?
Can I share the Postgres with other services?
Related services
Deploy on your VPS
Grafana paired with a dedicated PostgreSQL backend in one Pier stack. The PostgreSQL-backed deployment is what Grafana recommends for production — multi-user, HA-friendly, and avoids the SQLite write-lock issues that plague Grafana under load with multiple concurrent editors.
Deploy this service →