Published on

Prometheus + Grafana + Loki with docker-compose

Authors

This post shows a minimal setup to run Prometheus (metrics), Loki (logs) and Grafana (dashboards) locally via docker-compose.

Folder structure

obs/
├─ docker-compose.yml
├─ prometheus.yml
├─ loki-config.yml
└─ grafana/
   └─ provisioning/
      ├─ datasources/
      │  └─ datasources.yml
      └─ dashboards/
         ├─ dashboards.yml
         └─ my-dashboard.json

docker-compose.yml

version: '3.8'
services:
  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    command: --config.file=/etc/prometheus/prometheus.yml
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
    ports:
      - '9090:9090'

  loki:
    image: grafana/loki:2.9.0
    container_name: loki
    command: -config.file=/etc/loki/config.yml
    volumes:
      - ./loki-config.yml:/etc/loki/config.yml:ro
    ports:
      - '3100:3100'

  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
    volumes:
      - ./grafana/provisioning:/etc/grafana/provisioning:ro
    ports:
      - '3000:3000'
    depends_on:
      - prometheus
      - loki

prometheus.yml (example)

global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['prometheus:9090']
  # Add your apps here
  # - job_name: 'app'
  #   static_configs:
  #     - targets: ['app:8080']

loki-config.yml (example)

server:
  http_listen_port: 3100
  grpc_listen_port: 9096

ingester:
  lifecycler:
    address: 127.0.0.1
    ring:
      kvstore:
        store: inmemory
      replication_factor: 1
  chunk_idle_period: 5m
  chunk_retain_period: 30s
schema_config:
  configs:
    - from: 2020-10-15
      store: boltdb-shipper
      object_store: filesystem
      schema: v11
      index:
        prefix: index_
        period: 24h
storage_config:
  boltdb_shipper:
    active_index_directory: /loki/index
    cache_location: /loki/boltdb-cache
  filesystem:
    directory: /loki/chunks
limits_config:
  ingestion_rate_mb: 8
  ingestion_burst_size_mb: 16
  reject_old_samples: true
  reject_old_samples_max_age: 7d
chunk_store_config:
  max_look_back_period: 0s

Grafana provisioning

grafana/provisioning/datasources/datasources.yml:

apiVersion: 1
datasources:
  - name: Prometheus
    type: prometheus
    access: proxy
    url: http://prometheus:9090
    isDefault: true
  - name: Loki
    type: loki
    access: proxy
    url: http://loki:3100

grafana/provisioning/dashboards/dashboards.yml:

apiVersion: 1
providers:
  - name: 'default'
    orgId: 1
    folder: ''
    type: file
    options:
      path: /etc/grafana/provisioning/dashboards

Place any exported dashboard JSON files in grafana/provisioning/dashboards/ and Grafana will import them on startup.

Run it

cd obs
docker compose up -d

Notes

  • For production, add persistence volumes and secure credentials
  • Use Promtail or a log shipper to send container logs to Loki
  • Configure dashboards and alerts to your needs