Monitoring Docker containers is essential for maintaining healthy, high-performing containerized applications. This guide will walk you through setting up a robust monitoring system using Prometheus and Grafana, two powerful open-source tools that work seamlessly together to collect, store, and visualize metrics from your Docker environment.
🔹Understanding Container Monitoring Architecture
Before diving into the setup, it’s important to understand how the monitoring stack works. In a typical Docker monitoring setup with Prometheus and Grafana, the architecture consists of several components working together:
Prometheus serves as the central metrics collection and storage system. It scrapes metrics from various exporters at regular intervals (typically every 15 seconds) and stores them in its time-series database. Grafana connects to Prometheus as a data source and creates visualizations through dashboards. These components work with specialized exporters that collect specific metrics.
📊 Prometheus
An open-source monitoring system that collects and stores time-series data from configured targets, providing a powerful query language for analyzing metrics.
📈 Grafana
A visualization platform that transforms the metrics collected by Prometheus into informative and customizable dashboards.
🖥️ Node Exporter
A Prometheus exporter for collecting hardware and OS-level metrics from the host system, such as CPU usage, memory consumption, disk I/O, and network statistics.
📦 cAdvisor (Container Advisor)
A monitoring tool that collects, aggregates, and exports resource usage information from running containers, providing detailed insights into container performance.
🔹 Prerequisites
Before starting the setup process, ensure you have the following installed on your system:
- Docker Engine (latest stable version)
- Docker Compose
- Basic understanding of YAML configuration files
- Access to terminal/command line interface
🔹Setting Up Your Docker Monitoring Stack
1️⃣ Create Directory Structure
First, establish a proper directory structure to organize your configuration files:
mkdir -p docker-monitoring/prometheus
mkdir -p docker-monitoring/grafana/provisioning/datasources
mkdir -p docker-monitoring/grafana/provisioning/dashboards
cd docker-monitoring
2️⃣ Create Prometheus Configuration
Create a file named prometheus.yml
in the prometheus directory:
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'cadvisor'
static_configs:
- targets: ['cadvisor:8080']
- job_name: 'node-exporter'
static_configs:
- targets: ['node-exporter:9100']
This configuration tells Prometheus to scrape metrics from itself, cAdvisor (for container metrics), and Node Exporter (for host metrics) every 15 seconds.
3️⃣ Create Docker Compose File
Create a docker-compose.yml
file in the docker-monitoring directory:
version: '3.8'
networks:
monitoring:
driver: bridge
volumes:
prometheus_data: {}
grafana_data: {}
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
restart: unless-stopped
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'
- '--web.enable-lifecycle'
ports:
- "9090:9090"
networks:
- monitoring
node-exporter:
image: prom/node-exporter:latest
container_name: node-exporter
restart: unless-stopped
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.rootfs=/rootfs'
- '--path.sysfs=/host/sys'
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($|/)'
ports:
- "9100:9100"
networks:
- monitoring
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
container_name: cadvisor
restart: unless-stopped
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
- /dev/disk/:/dev/disk:ro
ports:
- "8080:8080"
networks:
- monitoring
grafana:
image: grafana/grafana:latest
container_name: grafana
restart: unless-stopped
volumes:
- grafana_data:/var/lib/grafana
- ./grafana/provisioning:/etc/grafana/provisioning
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=admin
- GF_USERS_ALLOW_SIGN_UP=false
ports:
- "3000:3000"
networks:
- monitoring
depends_on:
- prometheus
This Docker Compose file defines four services: Prometheus, Node Exporter, cAdvisor, and Grafana. Each service is configured with appropriate volumes, ports, and network settings.
4️⃣ Launch the Monitoring Stack
Start all the services using Docker Compose:
docker-compose up -d
This command launches all four containers in detached mode. You can verify that they’re running properly with:
docker-compose ps
🔹 Configuring Grafana
1️⃣ Access Grafana Dashboard
Open your web browser and navigate to http://localhost:3000
. You’ll be greeted with the Grafana login page. Use the following credentials:
- Username: admin
- Password: admin
You’ll be prompted to change the password on your first login for security purposes.
2️⃣ Add Prometheus as a Data Source
- Click on the gear icon (⚙️) in the left sidebar to open the Configuration menu
- Select “Data sources”
- Click “Add data source”
- Select “Prometheus” from the list
- Set the URL field to
http://prometheus:9090
- Click “Save & Test” to verify the connection
If everything is set up correctly, you should see a green “Data source is working” message.
3️⃣ Import Dashboards
- Click the “+” icon in the left sidebar
- Select “Import”
- Enter one of these dashboard IDs:
- 893 (Docker and system monitoring)
- 10619 (Docker containers)
- 1860 (Node Exporter Full)
- Click “Load”
- Select your Prometheus data source from the dropdown
- Click “Import”
These dashboards provide comprehensive monitoring for your Docker containers and host system metrics.
🔹Monitoring Multiple Hosts
If you need to monitor Docker containers across multiple hosts, you’ll need to install Node Exporter and cAdvisor on each host machine, then update your Prometheus configuration to scrape metrics from these additional targets.
Update Prometheus Configuration
Modify your prometheus.yml
file to include the additional hosts:
scrape_configs:
# Existing jobs...
- job_name: 'node-exporter-host2'
static_configs:
- targets: ['host2-ip:9100']
- job_name: 'cadvisor-host2'
static_configs:
- targets: ['host2-ip:8080']
After updating the configuration, reload Prometheus:
curl -X POST http://localhost:9090/-/reload
🔹Common Issues and Troubleshooting
⚠️ Issue 1: Grafana Can’t Connect to Prometheus
If you see a “Bad Gateway” error when trying to connect Grafana to Prometheus, check the following:
- Ensure Prometheus container is running:
docker ps | grep prometheus
- Check Prometheus logs for errors:
docker logs prometheus
- Verify network connectivity: In your Docker Compose file, make sure both services are on the same network
- Try using the container name instead of IP address in the Grafana data source configuration:
http://prometheus:9090
⚠️ Issue 2: Prometheus Configuration Permission Denied
If Prometheus fails to start with a permission error like “permission denied” for the configuration file:
- Check the permissions of your prometheus.yml file
- Ensure the file is readable by the Prometheus container
- Try adding these permissions:
chmod a+r prometheus/prometheus.yml
⚠️ Issue 3: cAdvisor Shows as Unhealthy
If the cAdvisor container shows as unhealthy:
- Check the logs:
docker logs prometheus-cAdvisor
- Verify the volumes are correctly mounted
- Ensure the host system allows access to the Docker socket
- Try an older or newer version of cAdvisor if the current one has issues
⚠️ Issue 4: No Data Appearing in Grafana Dashboards
If your dashboards aren’t showing any data:
- Verify Prometheus is scraping metrics successfully: visit
http://localhost:9090/targets
- Check the query expression in Grafana’s panel edit mode
- Adjust the time range in Grafana to ensure it covers when data was collected
- Restart the containers if needed:
docker-compose restart
🔹 Advanced Tips and Best Practices
💾 Persistence and Data Retention
To ensure your metrics data persists across container restarts, use named volumes for Prometheus and Grafana as shown in the Docker Compose file. You can adjust Prometheus’s data retention period by adding this to the command section:
command:
# Existing commands...
- '--storage.tsdb.retention.time=15d'
This sets data retention to 15 days, but you can adjust based on your storage capacity and requirements.
🔒 Security Considerations
- Change default credentials immediately after setup
- Consider using environment variables for sensitive information rather than hardcoding in files
- Restrict access to the Prometheus and Grafana interfaces using a reverse proxy with authentication
- Use network segmentation to isolate your monitoring stack from production services
⚡ Performance Optimization
- Adjust scrape intervals based on your needs – more frequent scraping provides higher resolution but increases resource usage
- Use recording rules in Prometheus for frequently used or complex queries
- Consider federation for large-scale deployments
- Monitor the resource usage of your monitoring stack itself
🔔 Adding Alerts
While this guide focuses on monitoring, you can extend your setup to include alerting:
- Define alerting rules in Prometheus
- Set up Alertmanager alongside Prometheus
- Configure notification channels in Grafana
- Create alert thresholds for critical metrics
🔹 Conclusion
You now have a fully functional Docker monitoring stack with Prometheus and Grafana. This setup provides comprehensive visibility into the performance and health of your Docker containers and host system. By following the tips and best practices outlined in this guide, you can ensure your monitoring system remains reliable, secure, and efficient.
Remember that monitoring is an ongoing process. As your containerized applications evolve, you may need to adjust your monitoring strategy by adding more exporters, creating custom dashboards, or implementing automated alerting based on your specific requirements.
🔹 References
- Reddit: Getting started Grafana Prometheus monitoring
- Reddit: What grafana dashboard you use to monitor docker
- Reddit: How do I add Prometheus as a datasource to Grafana
- Reddit: Docker monitoring with grafana and adding second host
- Building a Docker-based Monitoring System with Prometheus and Grafana
- Reddit: Prometheus not working after configuring docker named volumes
- Reddit: Monitoring docker-containers with grafana, prometheus & fluent-bit
- Reddit: Problems with Grafana and Prometheus Dashboard
- Reddit: The Essential Guide to Grafana Docker Monitoring
- Server Fault: Still can’t connect from my grafana docker container to prometheus
- Kubernetes Training: Prometheus & Grafana: Docker Compose Monitoring Tutorial
- Grafana Community: Connection error for data source Prometheus with grafana
- Dev.to: How to Set Up Grafana and Prometheus Using Docker
- Grafana Community: Tutorial Grafana Fundamentals Docker Prometheus
- GitHub: Docker Monitoring Workshop with Grafana Alloy, Prometheus and Loki
- YouTube: Install Grafana, Prometheus & Node Exporter with Docker
Leave a Reply