Full Observability Stack
Complete observability with Prometheus, Grafana, Loki, Tempo, and AlertManager
Overview
Prometheus is an open-source monitoring system developed originally by SoundCloud that has become the de facto standard for metrics collection and alerting in cloud-native environments. Built around a dimensional data model and powerful PromQL query language, Prometheus uses a pull-based approach to scrape metrics from targets at regular intervals. This makes it particularly well-suited for monitoring dynamic, containerized environments where services come and go frequently.
This comprehensive observability stack combines Prometheus for metrics collection and alerting with Grafana for visualization, Loki for log aggregation, Tempo for distributed tracing, and AlertManager for notification routing. Together, these components provide the three pillars of observability - metrics, logs, and traces - in a unified platform that shares common design principles and integrates natively. The stack includes essential exporters like Node Exporter for host metrics and cAdvisor for container metrics, creating a complete monitoring solution.
This configuration is ideal for DevOps teams implementing comprehensive observability for containerized applications, site reliability engineers building monitoring infrastructure, and organizations migrating from proprietary monitoring solutions to open-source alternatives. The stack provides enterprise-grade observability capabilities while maintaining the flexibility to customize and extend based on specific monitoring requirements, making it suitable for everything from small development teams to large-scale production deployments.
Key Features
- Pull-based metrics collection with automatic service discovery and multi-dimensional labeling
- PromQL query language for complex time-series analysis and alerting rule creation
- LogQL integration between Loki and Grafana for correlated metrics and logs analysis
- Distributed tracing with Tempo supporting OTLP, Jaeger, and Zipkin protocols
- Multi-channel alert routing through AlertManager with grouping, inhibition, and silencing
- Native Grafana dashboards with templating, annotations, and explore mode for ad-hoc queries
- Label-based log indexing in Loki for cost-effective storage without full-text indexing
- Container and host metrics collection via cAdvisor and Node Exporter integration
Common Use Cases
- 1Kubernetes cluster monitoring with pod, service, and node-level visibility
- 2Microservices observability with distributed tracing and service dependency mapping
- 3Infrastructure monitoring for bare metal servers, VMs, and cloud instances
- 4Application performance monitoring with custom metrics and business KPI tracking
- 5Cost-effective log aggregation for containerized applications without Elasticsearch overhead
- 6SRE teams implementing SLI/SLO monitoring with automated alerting workflows
- 7Development teams requiring local observability stack for testing and debugging
Prerequisites
- Docker host with minimum 4GB RAM (Prometheus 1GB+, Grafana 512MB+, Loki 1GB+)
- Available ports: 3000 (Grafana), 9090 (Prometheus), 3100 (Loki), 3200 (Tempo), 9093 (AlertManager)
- Basic understanding of PromQL for writing queries and creating custom dashboards
- Familiarity with YAML configuration for Prometheus scrape configs and Loki log parsing
- Knowledge of log parsing patterns and label extraction for Promtail configuration
- Understanding of OpenTelemetry standards for instrumenting applications with Tempo tracing
For development & testing. Review security settings, change default credentials, and test thoroughly before production use. See Terms
docker-compose.yml
docker-compose.yml
1services: 2 prometheus: 3 image: prom/prometheus:latest4 container_name: prometheus5 restart: unless-stopped6 ports: 7 - "${PROMETHEUS_PORT:-9090}:9090"8 command: 9 - '--config.file=/etc/prometheus/prometheus.yml'10 - '--storage.tsdb.path=/prometheus'11 - '--web.enable-lifecycle'12 - '--web.enable-remote-write-receiver'13 volumes: 14 - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro15 - ./prometheus/alerts:/etc/prometheus/alerts:ro16 - prometheus_data:/prometheus1718 alertmanager: 19 image: prom/alertmanager:latest20 container_name: alertmanager21 restart: unless-stopped22 ports: 23 - "${ALERTMANAGER_PORT:-9093}:9093"24 volumes: 25 - ./alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro26 - alertmanager_data:/alertmanager2728 grafana: 29 image: grafana/grafana:latest30 container_name: grafana31 restart: unless-stopped32 ports: 33 - "${GRAFANA_PORT:-3000}:3000"34 environment: 35 - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD:-admin}36 - GF_USERS_ALLOW_SIGN_UP=false37 volumes: 38 - grafana_data:/var/lib/grafana39 - ./grafana/provisioning:/etc/grafana/provisioning:ro40 depends_on: 41 - prometheus42 - loki43 - tempo4445 loki: 46 image: grafana/loki:latest47 container_name: loki48 restart: unless-stopped49 ports: 50 - "${LOKI_PORT:-3100}:3100"51 command: -config.file=/etc/loki/local-config.yaml52 volumes: 53 - ./loki/loki-config.yaml:/etc/loki/local-config.yaml:ro54 - loki_data:/loki5556 promtail: 57 image: grafana/promtail:latest58 container_name: promtail59 restart: unless-stopped60 volumes: 61 - ./promtail/promtail-config.yaml:/etc/promtail/config.yml:ro62 - /var/log:/var/log:ro63 - /var/lib/docker/containers:/var/lib/docker/containers:ro64 command: -config.file=/etc/promtail/config.yml65 depends_on: 66 - loki6768 tempo: 69 image: grafana/tempo:latest70 container_name: tempo71 restart: unless-stopped72 ports: 73 - "${TEMPO_PORT:-3200}:3200"74 - "4317:4317" # OTLP gRPC75 - "4318:4318" # OTLP HTTP76 command: -config.file=/etc/tempo/tempo.yaml77 volumes: 78 - ./tempo/tempo.yaml:/etc/tempo/tempo.yaml:ro79 - tempo_data:/var/tempo8081 node-exporter: 82 image: prom/node-exporter:latest83 container_name: node-exporter84 restart: unless-stopped85 ports: 86 - "${NODE_EXPORTER_PORT:-9100}:9100"87 volumes: 88 - /proc:/host/proc:ro89 - /sys:/host/sys:ro90 - /:/rootfs:ro91 command: 92 - '--path.procfs=/host/proc'93 - '--path.sysfs=/host/sys'94 - '--path.rootfs=/rootfs'9596 cadvisor: 97 image: gcr.io/cadvisor/cadvisor:latest98 container_name: cadvisor99 restart: unless-stopped100 ports: 101 - "${CADVISOR_PORT:-8080}:8080"102 volumes: 103 - /:/rootfs:ro104 - /var/run:/var/run:ro105 - /sys:/sys:ro106 - /var/lib/docker/:/var/lib/docker:ro107108volumes: 109 prometheus_data: 110 alertmanager_data: 111 grafana_data: 112 loki_data: 113 tempo_data: .env Template
.env
1# Full Observability Stack2PROMETHEUS_PORT=90903ALERTMANAGER_PORT=90934GRAFANA_PORT=30005LOKI_PORT=31006TEMPO_PORT=32007NODE_EXPORTER_PORT=91008CADVISOR_PORT=8080910# Grafana11GRAFANA_PASSWORD=adminUsage Notes
- 1Grafana at http://localhost:3000 (admin/admin)
- 2Prometheus at http://localhost:9090
- 3Loki for logs, Tempo for traces
- 4Create prometheus.yml, loki-config.yaml, tempo.yaml configs
- 5Node Exporter collects host metrics
- 6cAdvisor collects container metrics
Individual Services(8 services)
Copy individual services to mix and match with your existing compose files.
prometheus
prometheus:
image: prom/prometheus:latest
container_name: prometheus
restart: unless-stopped
ports:
- ${PROMETHEUS_PORT:-9090}:9090
command:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--storage.tsdb.path=/prometheus"
- "--web.enable-lifecycle"
- "--web.enable-remote-write-receiver"
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
- ./prometheus/alerts:/etc/prometheus/alerts:ro
- prometheus_data:/prometheus
alertmanager
alertmanager:
image: prom/alertmanager:latest
container_name: alertmanager
restart: unless-stopped
ports:
- ${ALERTMANAGER_PORT:-9093}:9093
volumes:
- ./alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro
- alertmanager_data:/alertmanager
grafana
grafana:
image: grafana/grafana:latest
container_name: grafana
restart: unless-stopped
ports:
- ${GRAFANA_PORT:-3000}:3000
environment:
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD:-admin}
- GF_USERS_ALLOW_SIGN_UP=false
volumes:
- grafana_data:/var/lib/grafana
- ./grafana/provisioning:/etc/grafana/provisioning:ro
depends_on:
- prometheus
- loki
- tempo
loki
loki:
image: grafana/loki:latest
container_name: loki
restart: unless-stopped
ports:
- ${LOKI_PORT:-3100}:3100
command: "-config.file=/etc/loki/local-config.yaml"
volumes:
- ./loki/loki-config.yaml:/etc/loki/local-config.yaml:ro
- loki_data:/loki
promtail
promtail:
image: grafana/promtail:latest
container_name: promtail
restart: unless-stopped
volumes:
- ./promtail/promtail-config.yaml:/etc/promtail/config.yml:ro
- /var/log:/var/log:ro
- /var/lib/docker/containers:/var/lib/docker/containers:ro
command: "-config.file=/etc/promtail/config.yml"
depends_on:
- loki
tempo
tempo:
image: grafana/tempo:latest
container_name: tempo
restart: unless-stopped
ports:
- ${TEMPO_PORT:-3200}:3200
- "4317:4317"
- "4318:4318"
command: "-config.file=/etc/tempo/tempo.yaml"
volumes:
- ./tempo/tempo.yaml:/etc/tempo/tempo.yaml:ro
- tempo_data:/var/tempo
node-exporter
node-exporter:
image: prom/node-exporter:latest
container_name: node-exporter
restart: unless-stopped
ports:
- ${NODE_EXPORTER_PORT:-9100}:9100
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- "--path.procfs=/host/proc"
- "--path.sysfs=/host/sys"
- "--path.rootfs=/rootfs"
cadvisor
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
container_name: cadvisor
restart: unless-stopped
ports:
- ${CADVISOR_PORT:-8080}:8080
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
Quick Start
terminal
1# 1. Create the compose file2cat > docker-compose.yml << 'EOF'3services:4 prometheus:5 image: prom/prometheus:latest6 container_name: prometheus7 restart: unless-stopped8 ports:9 - "${PROMETHEUS_PORT:-9090}:9090"10 command:11 - '--config.file=/etc/prometheus/prometheus.yml'12 - '--storage.tsdb.path=/prometheus'13 - '--web.enable-lifecycle'14 - '--web.enable-remote-write-receiver'15 volumes:16 - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro17 - ./prometheus/alerts:/etc/prometheus/alerts:ro18 - prometheus_data:/prometheus1920 alertmanager:21 image: prom/alertmanager:latest22 container_name: alertmanager23 restart: unless-stopped24 ports:25 - "${ALERTMANAGER_PORT:-9093}:9093"26 volumes:27 - ./alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro28 - alertmanager_data:/alertmanager2930 grafana:31 image: grafana/grafana:latest32 container_name: grafana33 restart: unless-stopped34 ports:35 - "${GRAFANA_PORT:-3000}:3000"36 environment:37 - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD:-admin}38 - GF_USERS_ALLOW_SIGN_UP=false39 volumes:40 - grafana_data:/var/lib/grafana41 - ./grafana/provisioning:/etc/grafana/provisioning:ro42 depends_on:43 - prometheus44 - loki45 - tempo4647 loki:48 image: grafana/loki:latest49 container_name: loki50 restart: unless-stopped51 ports:52 - "${LOKI_PORT:-3100}:3100"53 command: -config.file=/etc/loki/local-config.yaml54 volumes:55 - ./loki/loki-config.yaml:/etc/loki/local-config.yaml:ro56 - loki_data:/loki5758 promtail:59 image: grafana/promtail:latest60 container_name: promtail61 restart: unless-stopped62 volumes:63 - ./promtail/promtail-config.yaml:/etc/promtail/config.yml:ro64 - /var/log:/var/log:ro65 - /var/lib/docker/containers:/var/lib/docker/containers:ro66 command: -config.file=/etc/promtail/config.yml67 depends_on:68 - loki6970 tempo:71 image: grafana/tempo:latest72 container_name: tempo73 restart: unless-stopped74 ports:75 - "${TEMPO_PORT:-3200}:3200"76 - "4317:4317" # OTLP gRPC77 - "4318:4318" # OTLP HTTP78 command: -config.file=/etc/tempo/tempo.yaml79 volumes:80 - ./tempo/tempo.yaml:/etc/tempo/tempo.yaml:ro81 - tempo_data:/var/tempo8283 node-exporter:84 image: prom/node-exporter:latest85 container_name: node-exporter86 restart: unless-stopped87 ports:88 - "${NODE_EXPORTER_PORT:-9100}:9100"89 volumes:90 - /proc:/host/proc:ro91 - /sys:/host/sys:ro92 - /:/rootfs:ro93 command:94 - '--path.procfs=/host/proc'95 - '--path.sysfs=/host/sys'96 - '--path.rootfs=/rootfs'9798 cadvisor:99 image: gcr.io/cadvisor/cadvisor:latest100 container_name: cadvisor101 restart: unless-stopped102 ports:103 - "${CADVISOR_PORT:-8080}:8080"104 volumes:105 - /:/rootfs:ro106 - /var/run:/var/run:ro107 - /sys:/sys:ro108 - /var/lib/docker/:/var/lib/docker:ro109110volumes:111 prometheus_data:112 alertmanager_data:113 grafana_data:114 loki_data:115 tempo_data:116EOF117118# 2. Create the .env file119cat > .env << 'EOF'120# Full Observability Stack121PROMETHEUS_PORT=9090122ALERTMANAGER_PORT=9093123GRAFANA_PORT=3000124LOKI_PORT=3100125TEMPO_PORT=3200126NODE_EXPORTER_PORT=9100127CADVISOR_PORT=8080128129# Grafana130GRAFANA_PASSWORD=admin131EOF132133# 3. Start the services134docker compose up -d135136# 4. View logs137docker compose logs -fOne-Liner
Run this command to download and set up the recipe in one step:
terminal
1curl -fsSL https://docker.recipes/api/recipes/full-observability-stack/run | bashTroubleshooting
- Prometheus 'context deadline exceeded' errors: Increase scrape timeout and interval in prometheus.yml configuration
- Loki 'entry out of order' errors: Enable accept_out_of_order_writes in Loki config or fix Promtail timestamp parsing
- Grafana 'Bad Gateway' when querying Prometheus: Check Prometheus data source URL uses container name, not localhost
- High memory usage in Prometheus: Reduce metric retention period or increase storage.tsdb.retention.time parameter
- Tempo traces not appearing: Verify OTLP endpoints 4317/4318 are accessible and applications use correct trace headers
- AlertManager notifications not sending: Check alertmanager.yml routing rules and ensure webhook URLs are accessible from container
Community Notes
Loading...
Loading notes...
Download Recipe Kit
Get all files in a ready-to-deploy package
Includes docker-compose.yml, .env template, README, and license
Components
prometheusgrafanalokitempoalertmanagerpromtail
Tags
#prometheus#grafana#loki#tempo#alertmanager#observability#metrics#logs#traces
Category
Monitoring & ObservabilityAd Space
Shortcuts: C CopyF FavoriteD Download