In the modern DevOps landscape, the ability to visualize and react to infrastructure metrics is not just a luxury—it is a necessity. As microservices architectures grow in complexity, traditional logging alone becomes insufficient for diagnosing performance bottlenecks or understanding system health. This is where the powerful combination of Prometheus for time-series data collection and Grafana for visualization comes into play. In this guide, we will explore how to set up a robust monitoring stack that provides real-time insights into your application and infrastructure.
Understanding the Architecture
Prometheus operates on a pull-based architecture, meaning it scrapes metrics from configured endpoints at regular intervals. This approach ensures that Prometheus has full control over the scraping process, reducing the load on your services compared to push-based systems. Grafana, on the other hand, acts as the presentation layer. It connects to Prometheus as a data source, allowing you to create rich, interactive dashboards using PromQL (Prometheus Query Language).
Together, they form a decoupled ecosystem: Prometheus handles storage and retrieval, while Grafana handles user experience and alerting visualization. This separation of concerns allows you to scale each component independently based on your specific needs.
Setting Up with Docker Compose
The most efficient way to get started with this stack is using Docker Compose. This method ensures reproducibility and simplifies the deployment process across different environments, from local development to production.
Begin by creating a docker-compose.yml file. This configuration will spin up three services: Prometheus, Grafana, and a sample application (in this case, Node Exporter, which exposes system-level metrics).
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
ports:
- "9090:9090"
networks:
- monitoring
grafana:
image: grafana/grafana:latest
container_name: grafana
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
volumes:
- grafana_data:/var/lib/grafana
ports:
- "3000:3000"
depends_on:
- prometheus
networks:
- monitoring
node-exporter:
image: prom/node-exporter:latest
container_name: node-exporter
ports:
- "9100:9100"
networks:
- monitoring
volumes:
prometheus_data:
grafana_data:
networks:
monitoring:
driver: bridge
Configuring Prometheus Targets
Once the containers are running, you need to tell Prometheus where to scrape metrics from. Create a prometheus.yml file in the same directory as your docker-compose.yml. The configuration below defines two jobs: one for the Prometheus server itself (self-monitoring) and one for the Node Exporter.
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'node'
static_configs:
- targets: ['node-exporter:9100']
With this configuration, Prometheus will scrape metrics every 15 seconds. You can verify the setup by navigating to http://localhost:9090/targets in your browser. You should see both the prometheus and node jobs listed with a status of "UP".
Building Your First Dashboard
With data flowing into Prometheus, the next step is visualization. Log in to Grafana at http://localhost:3000 using the credentials defined in the Docker Compose file (admin/admin). Go to Connections > Data Sources and add a new Prometheus data source, pointing to http://prometheus:9090.
Create a new dashboard and add a new panel. Use PromQL to query your data. For example, to visualize CPU usage, you might use the query 100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100). This query calculates the average idle CPU time over 5 minutes and subtracts it from 100% to get the usage percentage.
Conclusion
Implementing Prometheus and Grafana is a foundational step toward achieving true observability in your infrastructure. While this setup covers the basics, the ecosystem offers much more, including alerting rules via Alertmanager and advanced service discovery mechanisms. By adopting these tools, you empower your team to move from reactive firefighting to proactive system management, ensuring high availability and performance for your applications.