1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135services:
# Grafana - Dashboard and visualization platform
grafana:
image: grafana/grafana:11.2.0
container_name: grafana
restart: unless-stopped
ports:
- "3001:3000"
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=admin
- GF_USERS_ALLOW_SIGN_UP=false
volumes:
- grafana-storage:/var/lib/grafana
- ./config/grafana/provisioning:/etc/grafana/provisioning
networks:
- observability
depends_on:
- prometheus
- loki
- tempo
# Prometheus - Metrics collection and storage
prometheus:
image: prom/prometheus:v2.54.1
container_name: prometheus
restart: unless-stopped
ports:
- "9091:9090"
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'
- '--storage.tsdb.retention.time=200h'
- '--web.enable-lifecycle'
volumes:
- ./config/prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus-storage:/prometheus
networks:
- observability
# OpenTelemetry Collector - Unified collection of traces, metrics, and logs
otel-collector:
image: otel/opentelemetry-collector-contrib:0.110.0
container_name: otel-collector
restart: unless-stopped
ports:
- "4317:4317" # OTLP gRPC receiver
- "4318:4318" # OTLP HTTP receiver
- "8889:8889" # Prometheus metrics exposed by the collector
- "13133:13133" # health_check extension
command: ["--config=/etc/otel-collector-config.yaml"]
volumes:
- ./config/otel-collector-config.yaml:/etc/otel-collector-config.yaml
networks:
- observability
depends_on:
- tempo
- prometheus
# Tempo - Distributed tracing backend
tempo:
image: grafana/tempo:2.6.0
container_name: tempo
restart: unless-stopped
user: "0" # Run as root to avoid permission issues
ports:
- "3200:3200" # Tempo HTTP API
- "14317:14317" # OTLP gRPC receiver
- "14318:14318" # OTLP HTTP receiver
command:
- "-config.file=/etc/tempo.yaml"
volumes:
- ./config/tempo.yaml:/etc/tempo.yaml
- tempo-storage:/tmp/tempo
networks:
- observability
# Loki - Log aggregation system
loki:
image: grafana/loki:3.1.0
container_name: loki
restart: unless-stopped
ports:
- "3100:3100"
command: -config.file=/etc/loki/local-config.yaml
volumes:
- loki-storage:/loki
networks:
- observability
# Promtail - Log shipping agent
promtail:
image: grafana/promtail:3.1.0
container_name: promtail
restart: unless-stopped
volumes:
- /var/log:/var/log:ro
- /var/lib/docker/containers:/var/lib/docker/containers:ro
- ./config/promtail-config.yml:/etc/promtail/config.yml
command: -config.file=/etc/promtail/config.yml
networks:
- observability
depends_on:
- loki
# Node Exporter - Host metrics collection
node-exporter:
image: prom/node-exporter:v1.8.2
container_name: node-exporter
restart: unless-stopped
ports:
- "9100:9100"
command:
- '--path.procfs=/host/proc'
- '--path.rootfs=/rootfs'
- '--path.sysfs=/host/sys'
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
networks:
- observability
volumes:
grafana-storage:
prometheus-storage:
loki-storage:
tempo-storage:
networks:
observability:
driver: bridge