Skip to content
appsgit

Deploy guide

How to self-host Grafana with Docker Compose

Grafana Docker Compose setup in 10 minutes: a pinned image, persistent storage, admin password from .env, plugins, HTTPS reverse proxy, backups and upgrades.

  • Updated
  • Beginner
  • About 10 minutes

You will need

  • 1 vCPU / 512 MB RAM (1 GB+ for many dashboards)
  • Docker + Docker Compose v2
  • A data source such as Prometheus, InfluxDB or Loki
  • A domain name (optional, for HTTPS)

What is Grafana?

Grafana is the open source standard for dashboards and observability. It connects to data sources such as Prometheus, Loki, InfluxDB, PostgreSQL, MySQL and Elasticsearch, and turns their data into dashboards, alerts and reports. Homelab users run it to graph server load, network traffic, Home Assistant sensors and power use. Grafana is open source under the AGPL-3.0 license.

Requirements

  • A Linux server with Docker Engine and Docker Compose v2. Grafana alone is light: 1 vCPU and 512 MB of RAM are enough to start.
  • At least one data source. If you have none yet, follow our Prometheus guide to collect server metrics first.
  • A domain name if you want HTTPS access.

Step 1: Prepare the server

This guide assumes Ubuntu 24.04 with Docker installed from the official Docker Engine guide.

mkdir -p ~/grafana && cd ~/grafana

Step 2: Create the Docker Compose file

Save this as docker-compose.yml:

services:
  grafana:
    image: grafana/grafana:13.2.3
    container_name: grafana
    restart: unless-stopped
    ports:
      - "127.0.0.1:3000:3000"
    environment:
      GF_SERVER_ROOT_URL: ${GF_SERVER_ROOT_URL}
      GF_SECURITY_ADMIN_USER: admin
      GF_SECURITY_ADMIN_PASSWORD: ${GF_ADMIN_PASSWORD}
      GF_USERS_ALLOW_SIGN_UP: "false"
      GF_ANALYTICS_REPORTING_ENABLED: "false"
      GF_PLUGINS_PREINSTALL: grafana-clock-panel
    volumes:
      - grafana_storage:/var/lib/grafana

volumes:
  grafana_storage: {}

Then create .env next to it:

GF_SERVER_ROOT_URL=https://grafana.example.com/
GF_ADMIN_PASSWORD=CHANGE_ME

Replace CHANGE_ME with the output of openssl rand -hex 32. The admin password variable only applies when the database is first created; after that, change it in the UI. Pinning 13.2.3 means upgrades only happen when you edit the tag.

Grafana's data lives in a named volume, which avoids permission problems: the container runs as user ID 472, so a bind-mounted folder must be owned by that user (sudo chown -R 472:0 ./data). If you want to keep a stack with metrics too, add Grafana to the same Compose file as Prometheus so it can reach http://prometheus:9090 by service name.

Step 3: Start and open the app

docker compose up -d
docker compose logs -f grafana

The port is bound to localhost, so either finish Step 4 first or use an SSH tunnel for a quick look: ssh -L 3000:127.0.0.1:3000 user@YOUR_SERVER_IP, then open http://localhost:3000. Sign in as admin with the password from .env.

Go to Connections, Data sources, Add data source, pick Prometheus (or your source), enter its URL and click Save & test. Then import a ready-made dashboard: Dashboards, New, Import, and enter dashboard ID 1860 (Node Exporter Full) from grafana.com.

Step 4: Put it behind HTTPS

With Caddy on the host:

grafana.example.com {
    reverse_proxy 127.0.0.1:3000
}

Caddy gets a Let's Encrypt certificate automatically and passes WebSockets, which Grafana Live uses. Make sure GF_SERVER_ROOT_URL matches the public URL, or login redirects and links in alert notifications point to the wrong place. The localhost binding matters: Docker-published ports bypass ufw, so "3000:3000" would expose plain HTTP even with the firewall enabled.

Backups and upgrades

Everything Grafana stores (dashboards, users, data source settings, alert rules) is in the SQLite database grafana.db inside the volume. Back it up with:

docker compose stop grafana
docker run --rm -v grafana_grafana_storage:/data -v "$PWD":/backup alpine \
  tar czf /backup/grafana-$(date +%F).tgz -C /data .
docker compose start grafana

For an extra safety net, keep important dashboards as JSON in Git (Dashboard, Export). To upgrade, change the tag to the new version, read the "What's new" and breaking changes notes for major releases, then:

docker compose pull && docker compose up -d

Troubleshooting

  • "GF_PATHS_DATA is not writable": a bind mount is owned by the wrong user. Run sudo chown -R 472:0 on the folder or use a named volume.
  • Admin password from .env does not work: the database already existed when you set it. Reset it with docker compose exec grafana grafana cli admin reset-admin-password NEW_PASSWORD.
  • "Origin not allowed" or redirect loops behind the proxy: GF_SERVER_ROOT_URL does not match the domain in the browser.
  • Data source test fails with "connection refused": inside the container, localhost is Grafana itself. Use the service name or the host's LAN IP.

Next steps

Set up alerting with a contact point such as email or Slack, add Loki for logs, provision data sources and dashboards from files so the setup is reproducible, and enable single sign-on through Authentik or another OAuth provider.

Spotted something out of date? Tell us and we will update the guide.

FAQ

Grafana questions

Still curious? Email info@appsgit.com.

What port does Grafana use?

Grafana listens on port 3000. Open http://SERVER_IP:3000, or your own domain once a reverse proxy terminates HTTPS in front of it.

What is the default Grafana login?

The default username and password are both admin, and Grafana asks you to change the password at first login. In Docker you can set a different initial password with the GF_SECURITY_ADMIN_PASSWORD environment variable, as this guide does.

Is Grafana free?

Yes. Grafana OSS is free and open source under the AGPL-3.0 license. Grafana Enterprise adds paid features such as enterprise data source plugins and reporting, and Grafana Cloud is a hosted service with a free tier.

Should I use grafana/grafana or grafana/grafana-enterprise?

grafana/grafana is the open source build. The Grafana docs recommend the Enterprise image as the default because it runs with the same features as OSS until you add a license, which makes a later upgrade easier. Pick grafana/grafana if you want a purely open source stack.

How do I install Grafana plugins in Docker?

Set GF_PLUGINS_PREINSTALL to a comma-separated list of plugin IDs. Grafana installs them on startup and stores them in the data volume.

Grafana vs Kibana?

Grafana is built for metrics dashboards across many data sources, including Prometheus, Loki, InfluxDB and SQL databases. Kibana is the dashboard layer for Elasticsearch and is strongest at searching and analysing logs stored there.