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

OpenTelemetry~18 min

Observability foundations with OpenTelemetry

Created: March 21, 2026 · Published: March 21, 2026

A practical guide for moving from instrumentation by fashion to instrumentation that answers real operational questions.

Beginner
Read guide
Reliability~12 min

SLO design for platform teams

Created: March 30, 2026 · Published: March 30, 2026

A short framework for choosing indicators and targets that help you negotiate reliability with product and engineering.

Intermediate
Read guide
Metrics~32 min

Metric downsampling with VictoriaMetrics in the free version

Created: April 10, 2026 · Published: April 10, 2026

VictoriaMetrics Enterprise provides native downsampling in cluster. On the free tier, you can approximate it with separate clusters, fan-out, and `-dedup.minScrapeInterval`.

Advanced
Read guide