Zum Inhalt

Grafana Loki mit Alloy per Docker: Docker-Container-Logs zentral sammeln und in Grafana durchsuchen

Veröffentlicht am 29. September 2026 · Geschätzte Lesezeit: 7 Minuten

Statt dich per docker logs durch einzelne Container zu klicken, sammelt Loki alle Logs zentral, speichert sie dauerhaft und macht sie mit LogQL durchsuchbar – verknüpft mit einer bestehenden oder frischen Grafana-Instanz. Alloy (der offizielle Nachfolger des eingestellten Promtail) erfasst die Logs direkt von der Docker-Schnittstelle und leitet sie an Loki weiter. Die Einrichtung dauert etwa 45 Minuten und funktioniert ohne Änderungen an deinen bestehenden Containern.[1][3]

Voraussetzungen

  • Ein Linux-Server mit Docker und Docker Compose
  • Ein Benutzerkonto mit Berechtigung für Docker
  • Port 3100 (Loki) und 3000 (Grafana) im Heimnetz frei
  • Etwa 512 MB freier Arbeitsspeicher zusätzlich zu deinen bestehenden Containern
  • Grundlegendes Verständnis von Docker Compose

1. Arbeitsordner anlegen

Erstelle einen Projektordner und wechsle hinein. Hier liegen später die Konfigurationsdateien und das Docker-Compose-Setup.

mkdir -p ~/docker/loki && cd ~/docker/loki

2. Loki-Konfiguration herunterladen

Loki braucht eine Konfigurationsdatei. Im Single-Binary-Modus (auch Monolith-Modus genannt) läuft Loki als einzelner Container und ist für den Heimgebrauch ideal.[3] Lade die offizielle Konfiguration herunter:

curl -sLO https://raw.githubusercontent.com/grafana/loki/v3.7.0/cmd/loki/loki-local-config.yaml
mv loki-local-config.yaml loki-config.yaml

Versionsnummer bei Bedarf anpassen

Zum Zeitpunkt dieser Anleitung ist Loki 3.7.0 aktuell. Prüfe die aktuell stabile Version auf GitHub und ersetze 3.7.0 bei Bedarf.

Die Konfiguration enthält bereits sinnvolle Standardwerte: Dateisystem-Speicher (kein S3 nötig), TSDB-Index, eingeschaltete Pattern-Ingester und deaktivierte Authentifizierung, weil Loki nur im Heimnetz erreichbar ist.[3]

3. Alloy-Konfiguration erstellen

Alloy sammelt die Logs. Erstelle eine Datei namens alloy-config.alloy im Projektordner. Die Alloy-Konfigurationssprache (.alloy) ist deklarativ und besteht aus Komponenten, die über Ein- und Ausgänge verbunden werden.[2]

// Docker-Container im laufenden System entdecken
discovery.docker "container_scrape" {
    host             = "unix:///var/run/docker.sock"
    refresh_interval = "5s"
}

// Logs der entdeckten Container erfassen
loki.source.docker "container_scrape" {
    host             = "unix:///var/run/docker.sock"
    targets          = discovery.docker.container_scrape.targets
    forward_to       = [loki.write.local_loki.receiver]
    refresh_interval = "5s"
}

// Gesammelte Logs an Loki senden
loki.write "local_loki" {
    endpoint {
        url       = "http://loki:3100/loki/api/v1/push"
    }
}

Was passiert hier? discovery.docker findet alle laufenden Docker-Container und aktualisiert die Liste alle fünf Sekunden. loki.source.docker liest die Logs dieser Container über den Docker-Socket und reicht sie weiter. loki.write sendet die Logs an die Loki-API unter dem Dienstnamen loki im selben Docker-Netzwerk.[2]

4. Docker-Compose-Datei anlegen

Erstelle eine Datei namens compose.yaml im Projektordner. Dieses Setup startet Loki, Alloy und Grafana in einem gemeinsamen Netzwerk.[1]

services:
  loki:
    image: grafana/loki:3.7.0
    container_name: loki
    restart: unless-stopped
    ports:
      - "3100:3100"
    volumes:
      - ./loki-config.yaml:/etc/loki/config.yaml:ro
      - loki-data:/tmp/loki
    command:
      - -config.file=/etc/loki/config.yaml
    healthcheck:
      test: ["CMD", "/usr/bin/loki", "-health"]
      interval: 30s
      timeout: 5s
      retries: 5
      start_period: 30s

  alloy:
    image: grafana/alloy:latest
    container_name: alloy
    restart: unless-stopped
    ports:
      - "12345:12345"
    volumes:
      - ./alloy-config.alloy:/etc/alloy/config.alloy:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
    command:
      - run
      - --server.http.listen-addr=0.0.0.0:12345
      - --storage.path=/var/lib/alloy/data
      - /etc/alloy/config.alloy
    depends_on:
      - loki
    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://localhost:12345/-/healthy"]
      interval: 30s
      timeout: 5s
      retries: 5
      start_period: 30s

  grafana:
    image: grafana/grafana:latest
    container_name: grafana-logs
    restart: unless-stopped
    ports:
      - "3000:3000"
    volumes:
      - grafana-data:/var/lib/grafana
    depends_on:
      - loki
    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://localhost:3000/api/health"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 60s

volumes:
  loki-data:
  grafana-data:

Erklärung der Komponenten:

  • loki – Der Log-Speicher. Verwendet die heruntergeladene Konfiguration und speichert die indizierten Logs im Docker-Volume loki-data.
  • alloy – Der Log-Sammler. Greift lesend auf den Docker-Socket zu (:ro), entdeckt Container und leitet ihre Logs an Loki weiter.
  • grafana – Die Visualisierungsoberfläche. Ermöglicht Log-Abfragen per LogQL und die Erstellung von Dashboards.

Docker-Socket ist sensibel

Der Alloy-Container benötigt lesenden Zugriff auf /var/run/docker.sock. Ein schreibgeschützter Zugriff (:ro) verhindert, dass Alloy Container manipulieren kann. Trotzdem gibt der Socket umfangreiche Informationen über alle Container und den Host preis. Stelle Port 12345 und 3000 niemals per Router-Portfreigabe ins Internet.

5. Konfiguration prüfen und starten

Prüfe zunächst die Compose-Datei auf Syntaxfehler:

docker compose config

Wenn keine Fehlermeldung erscheint, startest du alle Dienste:

docker compose up -d

Warte etwa 30 Sekunden, bis Loki und Alloy vollständig gestartet sind, und kontrolliere dann den Zustand:

docker compose ps

Alle drei Container sollten den Status Up und ein healthy-Healthcheck-Ergebnis zeigen.

6. Loki-Funktion testen

Prüfe, ob Loki bereit ist und Logs empfängt:

curl http://localhost:3100/ready

Die Antwort muss ready lauten.

curl -s http://localhost:3100/loki/api/v1/labels | python3 -m json.tool

Die Ausgabe sollte Labels wie container_name und source enthalten – ein Zeichen, dass bereits Logs eingetroffen sind.

curl -s http://localhost:12345/-/healthy

Eine leere Antwort mit HTTP-Status 200 zeigt, dass Alloy gesund ist.

7. Grafana-Datenquelle einrichten

Öffne Grafana im Browser: http://<server-ip>:3000. Ersetze <server-ip> durch die feste IP-Adresse deines Docker-Servers (z. B. 192.168.1.100). Beim ersten Start meldest du dich mit admin / admin an. Grafana fordert dich auf, ein sicheres Passwort zu vergeben.

Standard-Anmeldedaten sofort ändern

Der Benutzername admin und das initiale Passwort admin sind öffentlich bekannt. Lege direkt nach der ersten Anmeldung ein sicheres Passwort fest.

Gehe zu Connections → Add new connection und wähle Loki. Trage als URL http://loki:3100 ein (der Dienstname innerhalb des Docker-Netzwerks) und klicke auf Save & test. Grafana muss die Verbindung als erfolgreich bestätigen.[1]

8. Erste Log-Abfrage

Wechsle zu Explore (Menü links, Symbol mit den drei Balken). Wähle als Datenquelle Loki aus und gib folgende LogQL-Abfrage ein:

{source="docker"}

Klicke auf Run query. Jetzt sollten Logs aller laufenden Docker-Container erscheinen.[4]

LogQL-Grundlagen

  • {container_name="nginx"} – Logs nur eines bestimmten Containers
  • {container_name=~".+"} |= "error" – Logs mit dem Wort »error« in beliebigen Containern
  • {container_name="nginx"} |= "error" !="timeout" – Nginx-Fehler, aber keine Timeouts
  • rate({container_name="nginx"}[5m]) – Anzahl der Logzeilen pro Sekunde der letzten 5 Minuten

9. Backup und Rückweg

Ein Backup reicht aus, um den Zustand jederzeit wiederherzustellen:

cd ~/docker/loki
tar -czf loki-backup-2026-09-29.tar.gz compose.yaml loki-config.yaml alloy-config.alloy

Die eigentlichen Log-Daten liegen im Docker-Volume loki-data. Ein Docker-Volume-Backup erstellst du mit:

docker run --rm -v loki-data:/source -v $(pwd):/backup alpine tar -czf /backup/loki-data-backup-2026-09-29.tar.gz -C /source .

Log-Daten können sehr groß sein

Loki komprimiert Logs automatisch, aber bei vielen Containern können mehrere Gigabyte zusammenkommen. Das Einlesen des gesamten Volumes in ein Archiv dauert entsprechend.

Zum kompletten Entfernen aller Dienste inklusive Daten:

docker compose down -v

Ohne -v bleiben die Volumes erhalten und können mit docker compose up -d weiterverwendet werden.

Risiken und wichtige Hinweise

  1. Docker-Socket-Freigabe: Jeder Container mit Zugriff auf den Docker-Socket kann potenziell den gesamten Host kontrollieren. Alloy benötigt nur Leserechte – verwende zwingend :ro.
  2. Speicherverbrauch: Loki in der Single-Binary-Konfiguration benötigt ca. 256–512 MB RAM. Bei sehr vielen Logs (> 1 GB/Tag) kann der Speicherverbrauch steigen. Passe bei Bedarf das max_size_mb in loki-config.yaml unter embedded_cache an.
  3. Keine Authentifizierung: Diese Konfiguration setzt auth_enabled: false in Loki. Setze Loki niemals direkt ins Internet – verwende einen Reverse Proxy mit Zugriffsschutz oder ein VPN.
  4. Log-Rotation auf Host-Ebene: Wenn Docker die Logs bereits vor Alloy rotiert (siehe docker-log-rotation.md), kann Alloy ältere Logs nicht nachträglich einsammeln. Stellt sicher, dass Alloy läuft, bevor Logs automatisch gelöscht werden.

Typische Fehler

  1. Alloy kann Docker-Socket nicht lesen: /var/run/docker.sock existiert oder die Berechtigung fehlt. Prüfe mit ls -l /var/run/docker.sock, ob die Datei vorhanden und für die Docker-Gruppe lesbar ist.
  2. Alloy erreicht Loki nicht: Beide Dienste müssen im selben Docker-Netzwerk sein. Die Compose-Datei verbindet sie automatich über den Dienstnamen loki. Prüfe mit docker compose logs alloy, ob Verbindungsfehler (connection refused) auftauchen.
  3. Grafana-Datenquelle falsch konfiguriert: Die URL in Grafana muss http://loki:3100 lauten, nicht http://localhost:3100 – denn Grafana läuft selbst im Container und erreicht localhost nur innerhalb seines eigenen Containers.
  4. Keine Logs sichtbar: Stelle sicher, dass überhaupt Docker-Container laufen, die Logs produzieren. Starte testweise einen Container mit docker run -d --name test-logger alpine sh -c "while true; do echo 'test log entry'; sleep 5; done" und warte 30 Sekunden.

Fertig

Loki, Alloy und Grafana laufen nun unter diesen Adressen:

  • Loki-API: http://<server-ip>:3100
  • Alloy-UI: http://<server-ip>:12345
  • Grafana: http://<server-ip>:3000

Führe zum Abschluss diese Funktionsprüfung aus:

echo "=== Funktionsprüfung ==="

echo -n "1. Loki-Health: "
curl -sf http://localhost:3100/ready && echo "OK" || echo "FEHLER"

echo -n "2. Alloy-Health: "
curl -sf http://localhost:12345/-/healthy && echo "OK" || echo "FEHLER"

echo -n "3. Logs in Loki vorhanden: "
curl -sf http://localhost:3100/loki/api/v1/labels | python3 -m json.tool | grep -q container_name && echo "OK" || echo "KEINE LOGS"

echo -n "4. Grafana-Health: "
curl -sf http://localhost:3000/api/health | python3 -c "import sys,json; d=json.load(sys.stdin); print('OK -', d.get('message',''))" 2>/dev/null || echo "FEHLER"

Wenn alle vier Tests grün leuchten, sammelt Alloy die Logs aller Docker-Container, speichert sie in Loki und macht sie über Grafana durchsuchbar. Öffne Grafana, wechsle zu Explore und gib {source="docker"} ein – du solltest die Live-Logs deiner Container sehen.[4]

Sources: [1] https://grafana.com/docs/loki/latest/setup/install/docker — Grafana Loki Docker install documentation [2] https://raw.githubusercontent.com/grafana/loki/v3.7.0/examples/getting-started/alloy-local-config.yaml — Loki getting-started Alloy config [3] https://raw.githubusercontent.com/grafana/loki/v3.7.0/cmd/loki/loki-local-config.yaml — Loki single binary config [4] https://grafana.com/docs/loki/latest/get-started/quick-start/tutorial — Loki quick start tutorial