Back to guidesGuide

Prometheus for system metrics (cross-platform)

A practical foundation for scraping targets and validating stack health across Windows, Linux, macOS, and Docker.

Deploy Prometheus and validate operational metrics with a reproducible workflow, independent of your operating system.

Created: April 5, 2026

Published: April 5, 2026

Estimated time16 min
LevelBeginner
Before you startDocker and Docker Compose installed on your machine.
PlatformsDocker
WhatsAppXLinkedIn

Docker

This guide runs as a Docker-based lab. Use the Compose and configuration snippets in the article as the primary source of truth, and do not assume native OS support unless it is explicitly documented.

Docker and Docker Compose installed on your machine.At least one service exposing `/metrics` or an exporter you can scrape.Ports 9090 and 9100 free for the local lab.
Lab bootstrap
docker compose config
Stack start
docker compose up -d --build
Validation
docker compose ps
Prometheus is still one of the most direct ways to start with metrics because its model is simple: discover targets, scrape endpoints, and make queries available for alerts or dashboards. For local development or labs, Docker Compose gives you a clean and repeatable bootstrap.

Minimal lab architecture

  • One Prometheus container with a config file mounted from disk.
  • An initial target. This can be your app or an exporter such as node-exporter.
  • Basic persistence so you do not lose series on every restart.
What this setup optimizes for

This guide is not about high availability. The goal is a reliable local foundation for querying metrics and understanding the end-to-end flow.

Create the stack with Docker Compose

docker-compose.yml
services:
  prometheus:
    image: prom/prometheus:v2.54.1
    container_name: prometheus
    command:
      - --config.file=/etc/prometheus/prometheus.yml
      - --storage.tsdb.path=/prometheus
      - --web.enable-lifecycle
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prometheus_data:/prometheus

  node-exporter:
    image: prom/node-exporter:v1.8.2
    container_name: node-exporter
    ports:
      - "9100:9100"

volumes:
  prometheus_data:

Prometheus scrapes a simple exporter first so you can validate the pipeline before pointing it at your application.

1

Define the scrape file

Create a `prometheus/` directory next to `docker-compose.yml`.

Use a short `scrape_interval` for the lab and add the exporter target so ingestion is easy to validate.

prometheus/prometheus.yml
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: "prometheus"
    static_configs:
      - targets: ["prometheus:9090"]

  - job_name: "node"
    static_configs:
      - targets: ["node-exporter:9100"]
2

Start the stack

Run `docker compose up -d` and wait until Prometheus and node-exporter are healthy or running.

Open `http://localhost:9090/targets` and verify both jobs show as UP.

command
docker compose up -d

Validate that metrics are queryable

Do not call the deployment finished until you run specific queries. Targets tells you scraping works; Graph proves you already have useful data.

  • Query `up` to list active targets.
  • Query `rate(node_cpu_seconds_total[5m])` to validate exporter series.
  • Check `prometheus_tsdb_head_series` to understand how much data you are already storing.

Checklist before moving beyond the lab

  • Prometheus starts with valid config and no parse errors.
  • Targets stay UP consistently.
  • Persistence is mounted so series survive restarts.
  • You already have a plan for auth or secrets on sensitive endpoints.

Add your first real service

Once the lab works, replace the initial exporter or add a new job for your application. If you use OpenTelemetry Collector, Prometheus can scrape the collector endpoint or service-specific exporters.

Do I need service discovery for a first test?

No. Start with `static_configs` until the model is clear. Dynamic discovery becomes useful once the environment is less manual.

What if every target is DOWN?

Check networking and DNS names inside Docker Compose first. In local labs the most common mistake is using `localhost` instead of the service name between containers.

Recommended next step

The natural next step is wiring this Prometheus instance into Grafana and building a minimal host or application health dashboard.

More related reads

More related reads

Logs~35 min

Fix Loki label cardinality before incident logs disappear

Created: July 12, 2026 · Published: July 12, 2026

Learn how to detect explosive Loki labels, move volatile context out of the index, and validate that critical logs remain available during incidents.

LinuxDocker
Advanced
Read guide
Reliability~45 min

Design multi-window SLO burn-rate alerts without paging people for noise

Created: July 11, 2026 · Published: July 11, 2026

Learn how to define SLIs, error budget, PromQL, and promtool tests for burn-rate alerts that catch fast incidents without turning every short spike into a broken on-call shift.

Linux
Intermediate
Read guide
OpenTelemetry~45 min

Detect ingestion backpressure between OpenTelemetry, Data Prepper, and OpenSearch before telemetry drops

Created: July 10, 2026 · Published: July 10, 2026

Validate Collector, Data Prepper, and OpenSearch with parity, queue, and rejection metrics so traces, logs, or metrics do not disappear before you can explain the incident.

LinuxDocker
Advanced
Read guide