Published

Grafana

Dashboards and alerting for metrics, logs and traces: Grafana queries data sources such as Prometheus and Loki, draws them as panels and sends alert notifications. It stores dashboards, users and alert rules, not the data itself. Fits a home lab or a team that wants one place to watch its servers and services.

Resources by load level

What the app itself needs at each level, next to what we recommend for a server that runs only this app.

LevelWhat it meansApp requirementsRecommended
LightEstimateHome lab: up to 5 concurrent users, about 20 dashboards refreshing every minute or slower, up to 50 alert rules, 1-3 data sources such as Prometheus and Loki, SQLite.1 vCPU · 0.5 GiB RAM · 2.778 GiB disk1.32 vCPU · 2.1 GiB RAM · 12.625 GiB disk
MediumEstimateTeam: up to 25 concurrent users, up to 200 dashboards (10-20 panels, refresh 30 s or slower), up to 100 alert rules, under 5 data sources: the docs' Small tier.2 vCPU · 4 GiB RAM · 11.778 GiB disk2.52 vCPU · 6.3 GiB RAM · 22.975 GiB disk
HeavyEstimateDepartment: up to 100 concurrent users, about 1,000 dashboards, up to 500 alert rules, 5-25 data sources, one instance with database=postgres (the docs' Medium tier).4 vCPU · 8 GiB RAM · 21.778 GiB disk4.92 vCPU · 11.1 GiB RAM · 34.475 GiB disk

Recommended = app requirements + system baseline + safety headroom, under sizing policy 2026.10.0. Options stay at their defaults. “Estimate” means the sources give no number for that case, so it is worked out from them by the method stated under Components. How the numbers are built

Size it in the Stack Sizer

Ready-to-run files

Support level Supported

Compose template from the official sources; not yet verified by a run.

Create docker-compose

Components

What each component needs at each load level, before baseline and headroom.

vCPU / GiB RAM / GiB disk
ComponentLightMediumHeavySources
Grafana (UI, data source proxy and alerting) (app)1 / 0.5 / 2.7782 / 4 / 11.7784 / 8 / 21.778[11][12][13]
PostgreSQL (database)———
How the estimates are worked out
  • Grafana (UI, data source proxy and alerting) · Light: CPU and RAM: the documented minimum (512 MB, 1 core), enough for a few users and a small rule set. Disk: image 482,587,117 B compressed (0.449 GiB) + 1,426,266,112 B unpacked (1.328 GiB), both kept by the containerd store = 1.778 GiB + 1 GiB for grafana.db, plugins and the search index (ANAROQ's assumption) = 2.778.
  • Grafana (UI, data source proxy and alerting) · Medium: The docs' Small tier (under 25 concurrent users, 100 alert rules, 5 data sources, 200 dashboards) asks for 2 cores, 2-4 GB and a 10-20 GB database disk; this level fills the tier, so it takes the top of the RAM range and the bottom of the disk range. Disk: image 482,587,117 B compressed (0.449 GiB) + 1,426,266,112 B unpacked (1.328 GiB), both kept by the containerd store = 1.778 GiB + 10 GiB = 11.778.
  • Grafana (UI, data source proxy and alerting) · Heavy: The docs' Medium tier (25-200 concurrent users, 100-1,000 rules, 200-2,000 dashboards) asks for 4-8 cores, 8-16 GB and 20-50 GB per instance, with an external database; this level sits in its lower half on one instance and takes the lower bounds. Disk: image 482,587,117 B compressed (0.449 GiB) + 1,426,266,112 B unpacked (1.328 GiB), both kept by the containerd store = 1.778 GiB + 20 GiB = 21.778.
  • database · PostgreSQL: GF_DATABASE_MAX_OPEN_CONN=20 in the template keeps Grafana's pool (unbounded by default) inside the sidecar's 20-connection envelope. The database disk of each level stays on the Grafana component, so the sidecar's 5 GiB is extra room. Embedded metadata DB with the image's default config: equals the PostgreSQL profile's light preset (≤ 5 GB data, ≤ 20 concurrent connections) at every load level. Light preset method: shared_buffers 25% of RAM, worst-case work_mem/maintenance_work_mem budget, 0.5 GiB image + 5 GiB data + 1 GiB WAL.

Options that change resources

database

Database engine. SQLite (the default) is a file in /var/lib/grafana and suits small instances; the docs don't recommend it for production and call it unsuitable from the Medium tier on. PostgreSQL adds a separate container.

Default: sqlite

Ports

Public ports are meant to be reached from outside the stack, usually through a reverse proxy; internal ones stay on the stack's own network.

ComponentPortExposurePurposeSources
Grafana (UI, data source proxy and alerting)3000/tcpPublic, through a proxyWeb UI and HTTP API (HTTP; put behind a TLS reverse proxy)[2][5][6]
PostgreSQL5432/tcpInternal onlyPostgreSQL connections from Grafana (database=postgres only)[4][36]

Every port in the catalog, with conflicts between apps

User and permissions (UID/GID)

The user each container's process runs as, and the paths it writes to. A bind mount for one of these paths must be writable by that UID:GID.

ComponentUID:GIDUserStarts as rootWrites toSources
Grafana (UI, data source proxy and alerting)472:0grafanaNo/var/lib/grafana[2][6][7][8]
PostgreSQL999:999postgresYes, prepares its directories, then drops to this user/var/lib/postgresql/var/run/postgresql[29][30][36]
  • Grafana (UI, data source proxy and alerting): The image runs as uid 472 (user grafana, group root, gid 0) from the start; /var/lib/grafana is owned by it with mode 777, so a new named volume works as is. A bind mount must be writable by uid 472, or the container must run with --user set to the directory's owner, as the docs show.

Storage growth

How much each component's data grows per month at each load level, on top of the disk in the profile. A value marked Assumption is ANAROQ's stated assumption, not a figure from the sources; the notes say what it rests on.

GiB per month
ComponentLightMediumHeavySources
Grafana (UI, data source proxy and alerting)Assumption0.050.251[5][19]
PostgreSQLAssumption0.050.251[5][11]
What the growth figures rest on
  • Grafana (UI, data source proxy and alerting): Upstream gives no growth rate. Alert state history is written as annotations by default, and annotations are kept forever (max_age 0); each dashboard keeps 20 versions; logs go to the console, not the volume. Assumed: 0.05 GiB a month for this level's rules and dashboards. With database=postgres these rows grow in the PostgreSQL volume instead.
  • Grafana (UI, data source proxy and alerting): Upstream gives no growth rate. Alert state history is written as annotations by default, and annotations are kept forever (max_age 0); each dashboard keeps 20 versions; logs go to the console, not the volume. Assumed: 0.25 GiB a month for this level's rules and dashboards. With database=postgres these rows grow in the PostgreSQL volume instead.
  • Grafana (UI, data source proxy and alerting): Upstream gives no growth rate. Alert state history is written as annotations by default, and annotations are kept forever (max_age 0); each dashboard keeps 20 versions; logs go to the console, not the volume. Assumed: 1 GiB a month for this level's rules and dashboards. With database=postgres these rows grow in the PostgreSQL volume instead.
  • PostgreSQL: Only with database=postgres, and instead of the Grafana figure: the same annotation and dashboard-version rows, 0.05 GiB a month (ANAROQ's assumption). Set retention in [annotations.*] max_age to bound it.
  • PostgreSQL: Only with database=postgres, and instead of the Grafana figure: the same annotation and dashboard-version rows, 0.25 GiB a month (ANAROQ's assumption). Set retention in [annotations.*] max_age to bound it.
  • PostgreSQL: Only with database=postgres, and instead of the Grafana figure: the same annotation and dashboard-version rows, 1 GiB a month (ANAROQ's assumption). Set retention in [annotations.*] max_age to bound it.

Upgrade and rollback

How to move to a new version safely, and how to go back if it fails.

Back up first

Stop Grafana and copy the /var/lib/grafana volume (grafana.db and plugins); with database=postgres, take a pg_dump of the grafana database. Keep .env with it: GRAFANA_SECRET_KEY is needed to read the stored data source secrets. [10][22]

Upgrade steps

  1. Read the upgrade guide and the breaking changes of every version you skip. Before a major upgrade (for example 12.x to 13), move to the latest patch of your line and update all plugins first, as the v13 guide orders. [17][18][21]
  2. Back up (see below), set the new pinned tag grafana/grafana:X.Y.Z in the Compose file, then run docker compose pull and docker compose up -d. Settings live in the GF_* variables, so nothing in the container needs to be kept. [2][20]
  3. Grafana migrates its database at start (13.0 also moves dashboards and folders to unified storage). Watch docker compose logs grafana and /api/health, then run docker compose exec grafana grafana cli plugins update-all and restart. [9][18][20]

Roll back

Stop Grafana, restore the pre-upgrade copy of /var/lib/grafana (or the pg_dump), pin the previous tag and run docker compose up -d. Don't start an older version on a migrated database: after 13.0 it reads stale legacy tables. [18][22]

Known breaking changes

  • In 13.1.0: Zipkin was removed from the core data sources, and Azure and SigV4 authentication were removed from the core Prometheus data source. Check those data sources before upgrading. [17]
  • In 13.0.0: Dashboards and folders migrate once to unified storage at start; an older version then reads stale tables, so a downgrade needs the pre-upgrade backup. On SQLite the migration can hit 'database is locked'; the guide lists [unified_storage] settings for it. [18]
  • In 13.0.0: Data source APIs by numeric id are off (use uid), the Image Renderer runs only as a separate service, grafana-cli and grafana-server are gone (use grafana cli and grafana server), and Elasticsearch left the core data sources. [17][18]
  • In 12.4.0: Plugin processes no longer receive the host's environment variables by default; a backend plugin that read settings from the environment needs them configured another way. [17]
  • In 12.0.0: AngularJS support was removed, so Angular-based plugins and panels stop working; data source UIDs must match the documented format; from 11.x the annotation table is rewritten, which needs 2-3 times its size in free disk. [17][19]

Limits

  • SQLite (the default) suits small instances; the docs don't recommend it for production and call it unsuitable from the Medium tier on: use database=postgres. High availability (several instances, a shared session store) is not templated, and moving data from SQLite to another database later is up to you. [11]
  • These figures cover the Grafana server only. Prometheus, Loki and other data sources have their own sizing, and the Image Renderer (about 1 GB per worker, a separate service since 13.0) is not included. [11][18]
  • In a generated file Grafana cannot reach Prometheus or Loki as is: each app gets its own network (grafana-internal, prometheus-internal, loki-internal), and names resolve only on a shared one. Add prometheus-internal and/or loki-internal to the networks of the grafana service, then add data sources under Connections > Data sources as http://prometheus:9090 and http://loki:3100. Not localhost, which inside the container is Grafana itself. [25][26][27]
  • Plugins install at start from GF_PLUGINS_PREINSTALL (a comma-separated list, plugin@version to pin) into /var/lib/grafana/plugins; GF_INSTALL_PLUGINS is deprecated. The template sets none, and a plugin runs its code inside Grafana. [2][3][7]
  • The template uses grafana/grafana, the open-source edition under AGPLv3. The docs' examples default to grafana/grafana-enterprise, a separate image under another license that unlocks Enterprise features with a license key. [2][3][16]

Security

  • The admin account comes from GRAFANA_ADMIN_USER and GRAFANA_ADMIN_PASSWORD on the first start only; a later change in .env has no effect. Change the password in the UI, or recover it with docker compose exec grafana grafana cli admin reset-admin-password. [4][24]
  • Sign-up and anonymous access are off by default; keep them off on a server reachable from the internet. With anonymous access, anyone can list dashboards and data sources and send arbitrary queries to every data source. [5][23]
  • Data source passwords and tokens are encrypted with keys wrapped by GF_SECURITY_SECRET_KEY. The built-in default is public in defaults.ini, so the template sets GRAFANA_SECRET_KEY from .env; changing it later means re-encrypting the stored secrets. [4][5][10]
  • Viewers can send any query to the data sources of their organization, and the data source proxy can reach other services on the server's network. Give data sources least-privilege credentials, and restrict proxy targets with data_source_proxy_whitelist or a firewall. [4][23]
  • Privacy: by default Grafana sends anonymous usage counters to stats.grafana.org every 24 hours and checks grafana.com for new versions every 10 minutes. The disable-reporting option turns the counters off. [4][5]

Backup

  • Back up the /var/lib/grafana volume with Grafana stopped: grafana.db (SQLite) holds users, dashboards, alert rules and encrypted data source secrets, and plugins/ holds the installed plugins. With database=postgres, add a pg_dump of the grafana database. [3][22]
  • Store GRAFANA_SECRET_KEY from .env with the backup (encrypted, off the server): a restored database with a different key cannot decrypt its data source and notification secrets. [10][22]

Latest release

Newest upstream release
Grafana 13.2.4 [14][15]
This profile was checked against

Grafana 13.2.4

This profile was checked against the newest release.

Checked on
14 Oct 2026
State
Checked within the last 90 days
Where releases are published
Docker Hub tags

Latest releases of every app

Version

Profile status
Published
Checked against release
Grafana 13.2.4
Profile version
1.0.0
Figures verified
14 Oct 2026
Catalog release
2026.10.10
Sizing policy
2026.10.0
Compose file
Unverified

Sources

  1. Docker Docs: Control startup order in Compose (pg_isready healthcheck, service_healthy) (Official docs · read 11 Oct 2026)
  2. Grafana docs at v13.2.4: Run Grafana Docker image (compose: restart unless-stopped, '3000:3000', named volume at /var/lib/grafana, GF_SERVER_ROOT_URL, GF_PLUGINS_PREINSTALL) (Official Compose · read 14 Oct 2026)
  3. Grafana docs at v13.2.4: Configure a Grafana Docker image (grafana/grafana is OSS; Alpine recommended; GF_PATHS_DATA /var/lib/grafana; config only through environment variables) (Official docs · read 14 Oct 2026)
  4. Grafana docs at v13.2.4: Configure Grafana (GF_<SECTION>_<KEY> overrides; root_url, database, max_open_conn, reporting_enabled, admin_password set once on first run, secret_key, cookie_secure) (Official docs · read 14 Oct 2026)
  5. conf/defaults.ini at v13.2.4: http_port 3000, sqlite3 grafana.db, max_open_conn unset, reporting_enabled true, sign-up and anonymous off, public default secret_key, annotations kept forever (Official repository · read 14 Oct 2026)
  6. Dockerfile at v13.2.4: Alpine image with curl, GF_UID 472 and GF_GID 0, /var/lib/grafana owned by grafana and mode 777, EXPOSE 3000, USER 472, no HEALTHCHECK, no VOLUME (Official repository · read 14 Oct 2026)
  7. packaging/docker/run.sh at v13.2.4: checks that GF_PATHS_DATA is writable, GF_*__FILE secrets, GF_INSTALL_PLUGINS deprecated for GF_PLUGINS_PREINSTALL, exec grafana server with log mode console (Official repository · read 14 Oct 2026)
  8. Registry config of grafana/grafana:13.2.4 (linux/amd64): User 472, ExposedPorts 3000/tcp, no Volumes, no Healthcheck, Entrypoint /run.sh, Alpine 3.24.2 base (Measurement · read 14 Oct 2026)
  9. Grafana docs: HTTP API, Other (GET /api/health returns commit, database ok and version) (Official docs · read 14 Oct 2026)
  10. Grafana docs at v13.2.4: Configure database encryption (data source and notifier secrets encrypted with keys wrapped by secret_key; change it when you set up a new instance) (Official docs · read 14 Oct 2026)
  11. Grafana docs at v13.2.4: Install Grafana (minimum 512 MB and 1 core; Small/Medium/Large tiers; SQLite not recommended for production; MySQL 8.0+, PostgreSQL 12+) (Official docs · read 14 Oct 2026)
  12. Docker Hub tag grafana/grafana:13.2.4 (linux/amd64): 482,587,117 B compressed; 11 layers decompressed and counted: 1,426,266,112 B (Measurement · read 14 Oct 2026)
  13. Docker: the containerd image store keeps image layers both compressed and uncompressed (Official docs · read 14 Oct 2026)
  14. Docker Hub tags of grafana/grafana (13.2.4 newest stable on 2026-10-14, pushed 2026-10-13; 13.1.8, 13.0.11 and 12.4.13 are maintained lines; nightly tags are unreleased builds) (Official repository · read 14 Oct 2026)
  15. grafana.com versions API: stable channel 13.2.4, released 2026-10-13, license AGPLv3, not LTS (Official repository · read 14 Oct 2026)
  16. Grafana LICENSE at v13.2.4: GNU Affero General Public License v3 (Official repository · read 14 Oct 2026)
  17. CHANGELOG.md at v13.2.4: breaking changes of 13.1.0 (Zipkin, Prometheus Azure/SigV4 auth), 13.0.0 (Elasticsearch core data source, grafana-cli), 12.4.0 (plugin env) and 12.0.0 (Angular removed) (Release notes · read 14 Oct 2026)
  18. Grafana docs at v13.2.4: Upgrade to Grafana v13.0 (unified storage migration, downgrade needs the backup, numeric id data source APIs off, Image Renderer plugin removed) (Release notes · read 14 Oct 2026)
  19. Grafana docs at v13.2.4: Upgrade to Grafana v12.0 (data source UID format enforced, stricter plugin version checks, annotation table rewrite from 11.x) (Release notes · read 14 Oct 2026)
  20. Grafana docs at v13.2.4: Upgrade guide common tasks (Docker: keep settings in environment variables, pull the new image, recreate the container; then grafana cli plugins update-all) (Official docs · read 14 Oct 2026)
  21. Grafana docs at v13.2.4: Upgrade strategies (minor release every other month, major once a year, monthly patches for supported versions; 13.3 planned for 2026-10-20) (Official docs · read 14 Oct 2026)
  22. Grafana docs at v13.2.4: Back up Grafana (plugin data, SQLite grafana.db copied with Grafana stopped, pg_dump for PostgreSQL) (Official docs · read 14 Oct 2026)
  23. Grafana docs at v13.2.4: Configure security (data source proxy can reach internal services; Viewers can send any query to a data source; risks of anonymous access) (Official docs · read 14 Oct 2026)
  24. Grafana docs at v13.2.4: Grafana CLI (admin reset-admin-password, plugins install and update-all) (Official docs · read 14 Oct 2026)
  25. Grafana docs: Configure the Prometheus data source (server URL; in separate containers localhost is the Grafana container, use the Compose service name) (Official docs · read 14 Oct 2026)
  26. Grafana docs: Configure the Loki data source (built in, base URL only, Loki listens on port 3100 by default) (Official docs · read 14 Oct 2026)
  27. Docker Docs: Networking in Compose (containers on the same network reach each other by service name; services can join several networks) (Official docs · read 14 Oct 2026)
  28. Grafana Labs: Grafana Cloud plans (Free, Pro, Enterprise) (Official docs · read 14 Oct 2026)
  29. docker-library/postgres 18/trixie Dockerfile (postgres user 999:999, VOLUME /var/lib/postgresql) (Official repository · read 14 Oct 2026)
  30. docker-library/postgres 18/trixie docker-entrypoint.sh (chown, then gosu postgres) (Official repository · read 14 Oct 2026)
  31. PostgreSQL 18 documentation: 19.4 Resource Consumption (Official docs · read 10 Oct 2026)
  32. PostgreSQL 18 documentation: 19.3 Connections and Authentication (Official docs · read 10 Oct 2026)
  33. PostgreSQL 18 documentation: 19.10 Vacuuming (autovacuum settings) (Official docs · read 10 Oct 2026)
  34. PostgreSQL 18 documentation: 19.5 Write Ahead Log (max_wal_size) (Official docs · read 10 Oct 2026)
  35. PostgreSQL 18 documentation: 51.2 How Connections Are Established (Official docs · read 10 Oct 2026)
  36. Docker Official Image postgres: documentation (docker-library/docs) (Official docs · read 10 Oct 2026)
  37. Docker Hub: library/postgres tag 18.6 (compressed image sizes) (Official repository · read 10 Oct 2026)

All self-hosted apps