// Grafana Alloy config for the docker host (replaces Promtail, EOL since // 2026-03-02). Tails Docker container logs via docker_sd discovery, attaches // container_name/compose_service/stream labels, and pushes them to the // in-cluster Loki at loki-internal.lan (LAN-only Traefik Ingress on port 80). // River config produced by `alloy convert -f promtail` from an equivalent // Promtail YAML (so component names and argument shapes are guaranteed // correct for Alloy v1.18). discovery.docker "docker" { host = "unix:///var/run/docker.sock" refresh_interval = "5s" } loki.process "docker" { forward_to = [loki.write.default.receiver] // Parse docker json-file log lines // ({"log":"...","stream":"stdout","time":"..."}). stage.json { expressions = { log = "log", stream = "stream", } } stage.labels { values = { stream = null, } } } discovery.relabel "docker" { targets = [] // Strip leading / from container name. rule { source_labels = ["__meta_docker_container_name"] regex = "/(.*)" target_label = "container_name" } // Compose service name (if label is set). rule { source_labels = ["__meta_docker_container_label_com_docker_compose_service"] target_label = "compose_service" } // Log stream (stdout/stderr). rule { source_labels = ["__meta_docker_container_log_stream"] target_label = "stream" } // Mark the source so dashboards/alerts can distinguish the docker host. rule { target_label = "source" replacement = "docker-host" } } loki.source.docker "docker" { host = "unix:///var/run/docker.sock" targets = discovery.docker.docker.targets forward_to = [loki.process.docker.receiver] relabel_rules = discovery.relabel.docker.rules refresh_interval = "5s" } loki.write "default" { endpoint { url = "http://loki-internal.lan/loki/api/v1/push" } external_labels = {} }