Skip to content

Grafana

Setting Up Grafana on Docker Compose

Introduction To Grafana

Grafana is an open-source platform that is used for monitoring and observibility. It allows you to query, visualise, alert on, and understand the metrics no matter where they are stored.

Why Choose Grafana?

Grafana is a popular choice, and there are several reasons for this:

  • Open-Source and Flexibility - Grafana is an open-source platfrom, which means it’s free to use and highly customisable. With a variety of custom plugins that can be used to connect to virtually any data source.

  • Wide Range of Data Sources - Grafana supports a variety of data sources, including Prometheus, InfluxDB, Elasticsearch, MySQL, and PostgreSQL, making Grafana versatile for different types fo data and use cases.

  • Powerful Visualisation - Grafana offers a wide range of visualisation options such as graphs, heat maps, and histograms. This helps in creating detailed and informative dashboards.

  • Alerting & Notifications - Grafana includes integrated alerting capabilities, providing the ability to setup notifications for various conditions. Alerts can be sent to multiple channels like email, Slack, and webhooks.

  • Scalability - Grafana can be deployed on-premises or used as a managed service through Grafana Cloud, making it scalable for both small and large organisations

  • Community & Support - Being Open-Source, Grafana has a large community of users and contributors. This means that there are plenty of resources, plugins, and community support to help get the most out of Grafana.

Overall, Grafana is a robust tool for monitoring and analysing data, making it a go-to choice for many organisations looking to gain insights from their data.

Docker Compose, Prometheus and Env Examples

The Docker Compose example below, shows OAuth integration which is provided by Authentik but can be doing using other OAuth providers following Grafana’s documentation.

There is also the Grafana-DB, Prometheus and Node-Exporter referenced within the below configuration although these can be run as separate configurations; However, these are also services and integrations that Grafana is able to use and consume so these have been included into the configuration below:

Grafana

networks:
monitoring:
external: true
frontend:
external: true
backend:
external: true
volumes:
logs-grafana:
name: grafana
driver: local
driver_opts:
type: none
device: /mnt/HC_Volume_101788018/grafana
o: bind
logs-grafana-db:
name: grafana-db
driver: local
driver_opts:
type: none
device: /mnt/HC_Volume_101788018/grafana-db
o: bind
logs-prometheus:
name: prometheus
driver: local
driver_opts:
type: none
device: /mnt/HC_Volume_101788018/prometheus
o: bind
services:
grafana:
image: grafana/grafana
container_name: grafana
restart: unless-stopped
depends_on:
- grafana-db
ports:
- '3000:3000'
environment:
- GF_AUTH_GENERIC_OAUTH_ENABLED=true
- GF_AUTH_GENERIC_OAUTH_NAME=Authentik
- GF_AUTH_GENERIC_OAUTH_CLIENT_ID=grafana
- GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET=
- GF_AUTH_GENERIC_OAUTH_SCOPES=openid profile email
- GF_AUTH_GENERIC_OAUTH_AUTH_URL=https://authentik.<domain>/application/o/authorize/
- GF_AUTH_GENERIC_OAUTH_TOKEN_URL=https://authentik.<domain>/application/o/token/
- GF_AUTH_GENERIC_OAUTH_API_URL=https://authentik.<domain>/application/o/userinfo/
- GF_AUTH_SIGNOUT_REDIRECT_URL=https://grafana.<domain>/application/o/grafana/end-session/
# Optionally enable auto-login (bypasses Grafana login screen)
- GF_AUTH_OAUTH_AUTO_LOGIN=false
- GF_AUTH_GENERIC_OAUTH_ALLOW_ASSIGN_GRAFANA_ADMIN=true
# Optionally map user groups to Grafana roles
- GF_AUTH_GENERIC_OAUTH_ROLE_ATTRIBUTE_PATH=contains(groups, 'GrafanaAdmins') && 'Admin' || contains(groups, 'GrafanaEditors') && 'Editor' || 'Viewer'
- GF_DATABASE_HOST=grafana-db:3306
- GF_DATABASE_NAME=grafana
- GF_DATABASE_TYPE=mysql
- GF_DATABASE_PASSWORD=<db-password>
- GF_DATABASE_USER=grafana
- GF_EXPLORE_ENABLED=true
# These are the plugins I use. Feel free to modify the list
# - GF_INSTALL_PLUGINS: grafana-piechart-panel,natel-plotly-panel,grafana-clock-panel,camptocamp-prometheus-alertmanager-datasource,briangann-datatable-panel,grafana-worldmap-panel
- GF_LOG_LEVEL=info
- GF_SERVER_DOMAIN=grafana.<domain>
- GF_SERVER_ENFORCE_DOMAIN=true
- GF_SERVER_ROOT_URL=https://grafana.<domain>
- GF_SERVER_ROUTER_LOGGING=true
- GF_SESSION_LIFE_TIME=86400
- GF_USERS_ALLOW_SIGN_UP=false
- GF_USERS_AUTO_ASSIGN_ORGtrue
- GF_USERS_AUTO_ASSIGN_ORG_ROLE=Admin
#see https://github.com/grafana/grafana/issues/20096
- GODEBUG=netdns=go
labels:
- traefik.enable=true
- traefik.http.routers.grafana.rule=Host(`grafana.<domain>`)
- traefik.http.routers.grafana.entrypoints=https
- traefik.http.services.grafana.loadbalancer.server.port=3000
- traefik.http.routers.grafana.service=grafana
- traefik.http.services.grafana.loadbalancer.server.scheme=http
- traefik.http.routers.tls=true
- traefik.http.routers.grafana.tls.certresolver=myresolver
- "--certificatesresolvers.myresolver.acme.dnschallenge=true"
- "--certificatesresolvers.myresolver.acme.dnschallenge.provider=cloudflare"
volumes:
- logs:/var/lib/grafana
networks:
- frontend
- backend
- monitoring
grafana-db:
container_name: grafana-db
image: mysql:${MYSQL_VERSION}
restart: unless-stopped
volumes:
- logs:/var/lib/mysql:rw
environment:
MYSQL_USER: '${MYSQL_USER?err}'
MYSQL_DATABASE: '${MYSQL_DATABASE?err}'
MYSQL_PASSWORD: '${MYSQL_PASSWORD?err}'
MYSQL_ROOT_PASSWORD: '${MYSQL_ROOT_PASSWORD?err}'
networks:
- monitoring
prometheus:
image: prom/prometheus:${PROMETHEUS_VERSION?err}
container_name: prometheus
restart: unless-stopped
volumes:
- ${PWD}/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
- logs:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'
- '--web.enable-lifecycle'
expose:
- 9090
networks:
- monitoring
node-exporter:
image: prom/node-exporter:${NODE_EXPORTER_VERSION}
container_name: node-exporter
restart: unless-stopped
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.rootfs=/rootfs'
- '--path.sysfs=/host/sys'
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
expose:
- 9100
networks:
- monitoring
- backend

Prometheus

File is mapped as part of the above Docker Compose example, as prometheus.yml. The configuration itself contains period scrapers for Traefik.

global:
scrape_interval: 30s
scrape_timeout: 10s
evaluation_interval: 5s
scrape_configs:
- job_name: 'prometheus'
scrape_interval: 1m
static_configs:
- targets: ['localhost:9090']
- job_name: 'node'
static_configs:
- targets: ['node-exporter:9100']
- job_name: 'grafana'
scheme: http
static_configs:
- targets:
- grafana:3000
- job_name: 'traefik'
scheme: http
static_configs:
- targets:
- ['traefik:8899']

Env Example

Below is a sample Env file that is used by some of the applications in the Docker Compose example configuration above.

# General configuration
DOMAIN=<domain>
# Application versions
PROMETHEUS_VERSION=v3.0.1
MYSQL_VERSION=lts
GRAFANA_VERSION=11.4.0
NODE_EXPORTER_VERSION=v1.8.2
# MySQL variables
MYSQL_PASSWORD=
MYSQL_ROOT_PASSWORD=
MYSQL_USER=grafana
MYSQL_DATABASE=grafana

Start Grafana

Start Grafana by running the following command from within the folder / location where the docker compose file for Grafana has been stored.

docker compose up -d

Key Components of Docker Compose Configuration Explained

  • Image - Specifies the Grafana server image and tag
  • Ports - Exposes Grafana on specified port
  • Volumes - For media files and custom templates
  • Environment - Specific environment variables, that need to be passed into the Grafana container in order for it to function.
  • Labels - Used by Traefik to provide external access to the service, once the service all its dependancies have been started are "healthy" and Accessible, Public Service Name and what provider to use to check and obtain for an SSL Certificate

Volumes

  • Persistent Storage - The configuration above for Grafana is using a separate disk on the host specifically for the Logs and data that Grafana uses, creates and keeps for an historical overview. This is also done so space that Grafana requires does not affect other services that the host is currently running.