Data flow
/var/log/*.log and forwards each entry to Loki over HTTP.
Services
Prometheus
Collects and stores metrics. Scrapes Node Exporter every 15 seconds using the static target
node-exporter:9100. Configuration is mounted from ./prometheus/prometheus.yml.Image: prom/prometheus:latest
Port: 9090Node Exporter
Exposes host system metrics — CPU, RAM, disk, and network — as a Prometheus-compatible HTTP endpoint. No volume mounts required; it reads directly from the host’s
/proc and /sys filesystems.Image: prom/node-exporter:latest
Port: 9100Loki
Stores log streams indexed by label. Runs in single-binary mode with filesystem storage. Configuration is mounted from
./loki/loki-config.yml.Image: grafana/loki:latest
Port: 3100Promtail
Tails log files and pushes them to Loki. The host’s
/var/log directory is bind-mounted read-only, and the Promtail config is mounted from ./promtail/promtail-config.yml.Image: grafana/promtail:latest
Port: none exposed to hostGrafana
Visualises metrics from Prometheus and logs from Loki in a unified dashboard. The admin password is set via the
GF_SECURITY_ADMIN_PASSWORD environment variable.Image: grafana/grafana:latest
Port: 3000Port mapping
| Service | Container port | Host port | Protocol |
|---|---|---|---|
| Grafana | 3000 | 3000 | HTTP |
| Loki | 3100 | 3100 | HTTP |
| Prometheus | 9090 | 9090 | HTTP |
| Node Exporter | 9100 | 9100 | HTTP |
| Promtail | 9080 | not mapped | HTTP |
Promtail’s HTTP server listens on container port
9080 (set by server.http_listen_port in promtail-config.yml) but no host port mapping is defined in docker-compose.yml. Port 9080 is only reachable from other containers on the Docker network — not from your host browser.Prometheus scrape configuration
Prometheus is configured with a globalscrape_interval of 15s. It has one scrape job, node-exporter, targeting Node Exporter by container name:
prometheus/prometheus.yml
node-exporter resolves to the Node Exporter container’s IP automatically. You do not need to hard-code any IP address.
Promtail log collection
Promtail reads every file matching/var/log/*.log and labels each log stream with job="varlogs". It tracks read positions in /tmp/positions.yaml so that restarts do not re-send already-processed lines.
promtail/promtail-config.yml
clients entry uses the container name loki as the hostname. Promtail pushes to Loki’s ingest endpoint at http://loki:3100/loki/api/v1/push.
The host’s
/var/log directory is mounted into the Promtail container at /var/log as read-only (ro). Promtail can read log files but cannot write to or delete them.Loki storage configuration
Loki runs without authentication (auth_enabled: false) and stores data on the local filesystem under the /loki path prefix. Chunks and index rules are kept in separate subdirectories:
loki/loki-config.yml
- Schema version: v13 with TSDB store, active from
2020-10-24. - Object store:
filesystem— data lives inside the container at/loki/chunks. - Index: prefix
index_, rotated every 24 hours. - Replication factor: 1 (single node, no replication).
- Ring coordination: in-memory KV store bound to
127.0.0.1, suitable for single-instance deployments.
Network connectivity
All five containers communicate using Docker’s default bridge network. Services reference each other by container name:| Connection | URL used |
|---|---|
| Prometheus → Node Exporter | http://node-exporter:9100/metrics |
| Promtail → Loki | http://loki:3100/loki/api/v1/push |
| Grafana → Prometheus | http://prometheus:9090 |
| Grafana → Loki | http://loki:3100 |
localhost.