Loki can ingest logs directly from Docker containers without needing a separate agent like Promtail.
Let’s see Loki’s Docker driver in action. Imagine you have a simple Nginx container running:
docker run -d --name nginx-test -p 8080:80 nginx
Now, if you want Loki to grab these logs, you’d typically have Promtail watching the Docker socket and parsing stdout/stderr. But with the Docker driver, Loki itself reaches out and pulls them. You configure Loki to use this driver in its scrape_configs within loki-local.yaml:
scrape_configs:
- job_name: docker-logs
static_configs:
- targets:
- localhost
labels:
job: docker-logs
__address__: docker:2375 # Or your Docker daemon address
docker_sd_configs:
- host: unix:///var/run/docker.sock # Or your Docker daemon socket
relabel_configs:
- source_labels: [__meta_docker_container_name]
regex: (.*)
target_label: container
- source_labels: [__meta_docker_container_id]
target_label: container_id
- source_labels: [__meta_docker_container_image_name]
regex: (.*)
target_label: image
- source_labels: [__meta_docker_container_label_com_docker_compose_service]
target_label: service
- source_labels: [__meta_docker_container_label_com_docker_compose_project]
target_label: project
- source_labels: [__meta_docker_container_label_com_docker_compose_project]
target_label: __path__
separator: '/'
regex: '^(.*)$'
replacement: '/var/lib/docker/containers/$1/$1-json.log' # Adjust path as needed
Here’s how it breaks down:
docker_sd_configs: This is the service discovery part. Loki uses it to find Docker containers. It points to your Docker daemon’s socket.relabel_configs: This is where the magic happens for mapping Docker metadata to Loki labels.__meta_docker_container_namebecomes thecontainerlabel.__meta_docker_container_idbecomescontainer_id.__meta_docker_container_image_namebecomesimage.- If you’re using Docker Compose,
__meta_docker_container_label_com_docker_compose_serviceand__meta_docker_container_label_com_docker_compose_projectbecomeserviceandprojectlabels respectively. - Crucially, the
__path__relabeling attempts to construct the path to the container’s log file on the Docker host. By default, Docker stores logs in JSON files under/var/lib/docker/containers/<container_id>/<container_id>-json.log. The configuration above tries to infer this path using theprojectlabel, but you might need to adjust thereplacementregex based on your Docker setup.
Once configured and Loki is restarted, it will start polling these log files. You can then query your Nginx logs in Grafana:
{job="docker-logs", container="nginx-test"}
The core problem this solves is simplifying log collection infrastructure. Instead of deploying and managing Promtail agents on every host where containers run, Loki itself becomes aware of your container environment and directly accesses the log files. This is particularly powerful in Kubernetes environments where the Docker driver can be configured to point to the container runtime’s log directory (e.g., /var/log/containers/ for containerd/docker).
The __path__ relabeling is the most intricate part. While Loki can discover containers, it needs to know where their logs are. The default Docker logging driver writes logs to JSON files. The relabel_configs use metadata discovered by docker_sd_configs to construct the path to these files. The regex ^(.*)$ and replacement /var/lib/docker/containers/$1/$1-json.log is a common pattern, assuming your Docker daemon is configured to use the json-file log driver and logs are stored in the default location. If you’re using a different logging driver or a custom log rotation setup, you’ll need to adapt this __path__ configuration significantly.
This approach bypasses the need for Promtail to run as a DaemonSet or on every node, reducing operational overhead and resource consumption. Loki directly reads the log files produced by the Docker daemon, making it a more integrated solution for containerized environments.
The next hurdle is handling log rotation and ensuring Loki can still access rotated files.