Halloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PCHalloween DealsAmazon USOctober picks are moving - compare before checkoutAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk10 min

Prometheus Docker Compose File: Complete Monitoring Stack Setup

A practical Prometheus Docker Compose guide covering prometheus.yml mounts, persistent storage, cAdvisor targets, Grafana integration, reloads, security, and troubleshooting.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A reliable Prometheus Compose setup uses two files: a compose.yml that runs Prometheus and its exporters, and a prometheus.yml that defines scrape jobs. Mount the configuration at /etc/prometheus/prometheus.yml, persist the time-series database at /prometheus, and address other containers by their Compose service names.

What this Docker Compose stack does

Docker Compose is a tool for defining and running multi-container applications from one YAML file. In a monitoring project, Compose gives Prometheus a repeatable way to start, stop, inspect, rebuild, and log the containers that provide metrics.

As an Amazon Associate I earn from qualifying purchases.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Prometheus collects metrics by scraping HTTP endpoints exposed by monitored targets. A basic project contains:

  • Prometheus: stores time-series data and provides the web interface on port 9090.
  • Exporters or instrumented applications: expose metrics for Prometheus to scrape.
  • Persistent storage: keeps the Prometheus data directory across container recreation and restarts.

The following examples use the official Prometheus image and a standard cAdvisor image. Image tags are deliberately unpinned in the examples; for production, choose and test a specific tag rather than accepting an unexpected future change.

Minimal Prometheus-only Compose file

Create a directory such as prometheus-compose. Put this file in it as compose.yml:

services:
  prometheus:
    image: prom/prometheus
    command:
      - --config.file=/etc/prometheus/prometheus.yml
      - --storage.tsdb.path=/prometheus
    ports:
      - '127.0.0.1:9090:9090'
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prometheus-data:/prometheus

volumes:
  prometheus-data:

The loopback address in the port mapping makes the web interface reachable only from the Docker host. If the service must be reachable from another machine, use a firewall and an authenticated reverse proxy rather than exposing an unauthenticated Prometheus interface broadly.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Why each line matters

  • --config.file tells Prometheus exactly where the mounted configuration lives. The default path is commonly the same, but stating it removes ambiguity.
  • --storage.tsdb.path=/prometheus puts the time-series database in the directory backed by the named volume.
  • ./prometheus.yml:/etc/prometheus/prometheus.yml:ro bind-mounts the host file read-only. Prometheus can read it, but a process in the container cannot modify the host copy.
  • prometheus-data:/prometheus gives the database durable storage. Removing the container does not remove this named volume; removing the volume does.
  • 127.0.0.1:9090:9090 maps host port 9090 to the container’s port 9090 without publishing it on every host interface.

Write the Prometheus configuration

Create prometheus.yml beside compose.yml:

global:
  scrape_interval: 15s
  evaluation_interval: 15s

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

The global block supplies defaults. scrape_interval: 15s means Prometheus normally requests metrics from each target every 15 seconds. evaluation_interval: 15s controls how often recording and alerting rules are evaluated when rules are configured.

Each entry under scrape_configs is a job. The static_configs list contains target addresses. Inside a Compose network, prometheus resolves to the Prometheus service, so prometheus:9090 is the correct target. Do not use localhost:9090 for another container: inside the Prometheus container, localhost means Prometheus itself.

Loading recording and alerting rules

Rules are separate YAML files. Add a rule_files entry when you have them:

global:
  scrape_interval: 15s
  evaluation_interval: 15s

rule_files:
  - /etc/prometheus/rules/*.yml

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

Mount a host rules directory read-only if you use this layout:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
volumes:
  - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
  - ./rules:/etc/prometheus/rules:ro
  - prometheus-data:/prometheus

A configuration file can be syntactically valid while a target is unreachable. Validation and the Targets page are both required checks.

Start and verify the stack

  1. Create the files. Ensure compose.yml and prometheus.yml are in the same directory, with indentation made from spaces rather than tabs.
  2. Render the Compose model. Run docker compose config. This catches YAML and Compose interpolation errors before containers start.
  3. Start in the background. Run docker compose up -d. The older command docker-compose up belongs to the legacy Compose executable; current installations generally use the space-separated command.
  4. Check container state. Run docker compose ps. The Prometheus container should show a running state and a port mapping for 9090.
  5. Read startup logs. Run docker compose logs prometheus. Add -f to follow the stream while diagnosing startup or scrape problems.
  6. Open the interface. Visit http://localhost:9090 on the Docker host. The expression browser can query stored series.
  7. Inspect targets. Open the targets page in the Prometheus interface and confirm the prometheus job is UP. A target marked down needs network or endpoint diagnosis even when the container itself is running.
  8. Check the endpoint directly. Visit http://localhost:9090/metrics to confirm Prometheus is exposing its own metrics endpoint.

When a service is changed, apply the new definition with docker compose up -d. Use docker compose restart prometheus only when a restart is actually needed; a configuration reload can avoid interrupting the process.

Full example with cAdvisor and Redis

The official cAdvisor Compose pattern adds cadvisor and redis services. cAdvisor exposes container and host-level container metrics on port 8080. Redis is an application service in this template; merely publishing port 6379 does not make Redis metrics available to Prometheus. To monitor Redis-specific statistics, deploy a Redis exporter and add that exporter as a separate scrape target.

For a Linux Docker host, this is a practical starting point:

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
services:
  prometheus:
    image: prom/prometheus
    command:
      - --config.file=/etc/prometheus/prometheus.yml
      - --storage.tsdb.path=/prometheus
    ports:
      - '127.0.0.1:9090:9090'
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prometheus-data:/prometheus
    depends_on:
      - cadvisor

  cadvisor:
    image: gcr.io/cadvisor/cadvisor
    ports:
      - '127.0.0.1:8080:8080'
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:ro
      - /sys:/sys:ro
      - /var/lib/docker:/var/lib/docker:ro
      - /dev/disk:/dev/disk:ro

  redis:
    image: redis
    ports:
      - '127.0.0.1:6379:6379'

volumes:
  prometheus-data:

The host mounts give cAdvisor visibility into the filesystems, runtime state, kernel information, and Docker storage it needs to observe containers. They are intentionally read-only. The exact mounts can differ with the container runtime, operating system, rootless Docker, and security policy; if cAdvisor starts but reports permission or missing-statistics errors, inspect its logs and adapt the mounts to that host.

depends_on expresses startup order. It does not prove that cAdvisor is ready to serve metrics, nor does it restart a failed dependency. Prometheus will retry scrapes according to its normal behavior, so readiness still has to be checked on the Targets page.

Scrape cAdvisor by service name

Replace the minimal configuration with this one to collect both Prometheus and cAdvisor data:

global:
  scrape_interval: 15s
  evaluation_interval: 15s

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

  - job_name: cadvisor
    scrape_interval: 5s
    static_configs:
      - targets: ['cadvisor:8080']

The cAdvisor job uses a five-second interval, while the global default remains 15 seconds for jobs that do not override it. Faster scraping increases collection frequency and storage activity, so use it only where the extra resolution is useful.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

From the Docker host, cAdvisor is available at http://localhost:8080 with the example port mapping. From Prometheus, the correct address is cadvisor:8080. The two addresses are not interchangeable: one is for a host browser, the other is for container-to-container DNS.

Persisting Prometheus data correctly

Prometheus stores its time-series database under /prometheus in the official container guidance. Without a named volume or bind mount at that path, data in the container’s writable layer can disappear when the container is replaced or its storage is removed.

Named volume

The examples use a named volume:

volumes:
  - prometheus-data:/prometheus

This is the least intrusive option for a single host. Docker manages the volume location, and it remains available when you run docker compose down without the -v option. Running docker compose down -v removes declared volumes and therefore destroys the stored series.

Bind mount

A bind mount lets you choose the host directory and use host-level backup tooling:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
volumes:
  - ./data/prometheus:/prometheus

Create the directory first and verify that the container’s Prometheus process can write to it. Bind mounts make permissions, ownership, disk capacity, and host cleanup policies your responsibility.

Operational checks

  • Monitor free space on the filesystem holding the volume.
  • Do not treat a container image update as a backup; back up the data volume independently.
  • Keep the configuration and rules under version control, but do not assume that configuration files contain the time-series database.
  • Before deleting a project, distinguish docker compose down from docker compose down -v.

Adding Grafana to the same project

Grafana is a visualization layer, not a replacement for Prometheus. Add it when you need dashboards and user-facing charts. A simple service can share the Compose network:

  grafana:
    image: grafana/grafana
    ports:
      - '127.0.0.1:3000:3000'
    depends_on:
      - prometheus
    volumes:
      - grafana-data:/var/lib/grafana

Add the corresponding top-level volume:

volumes:
  prometheus-data:
  grafana-data:

When configuring the Prometheus data source in Grafana, use http://prometheus:9090. Using http://localhost:9090 from inside the Grafana container points back to Grafana itself, not to the Prometheus service. Keep Grafana’s port bound to loopback or protect it with your chosen authentication and reverse-proxy controls before exposing it outside the host.

Reloading configuration without replacing the container

Prometheus can reload a valid configuration after receiving SIGHUP or a POST request to /-/reload. The POST endpoint is available only when lifecycle support is enabled.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Add the lifecycle flag to the Prometheus command:

command:
  - --config.file=/etc/prometheus/prometheus.yml
  - --storage.tsdb.path=/prometheus
  - --web.enable-lifecycle

After editing the bind-mounted file, validate the Compose model and then request a reload:

docker compose exec prometheus wget -qO- --post-data='' http://localhost:9090/-/reload

You can also send SIGHUP to the container’s main process with Docker tooling. Restrict access to the lifecycle endpoint; do not publish an unauthenticated administration surface to an untrusted network.

If the new YAML is malformed or otherwise invalid, Prometheus keeps the last valid configuration rather than applying the broken one. Check docker compose logs prometheus, correct the file, and retry. A reload does not create a missing target, repair DNS, or change the Compose network.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Docker daemon metrics are a separate path

Docker can expose metrics about the Docker daemon itself through the daemon’s metrics-addr setting, commonly 127.0.0.1:9323. Docker documents that metric names are still in active development and that this endpoint currently monitors Docker itself, not the applications running in containers.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Do not confuse three different endpoints:

  • prometheus:9090 is Prometheus’s own endpoint.
  • cadvisor:8080 reports container-observation data from cAdvisor.
  • The daemon endpoint on port 9323 reports Docker engine metrics.

Scraping the daemon endpoint from a container requires deliberate host reachability and firewall decisions. It is not a substitute for instrumenting an application or deploying an exporter.

Minimal versus fuller Compose designs

Aspect Prometheus-only Prometheus plus cAdvisor and Redis
Services One Prometheus service Prometheus, cAdvisor, and Redis
Monitored targets Prometheus itself unless more jobs are added Prometheus and cAdvisor by default; Redis needs an exporter for Redis metrics
Container coverage No automatic container telemetry cAdvisor supplies container-oriented telemetry
Scrape intervals 15-second global default 15-second default, with cAdvisor at 5 seconds in the example
Persistence Named volume at /prometheus The same Prometheus volume; add a separate volume for Grafana if used
Published ports 9090 9090, 8080, and 6379 in the template; bind them narrowly where possible
Operational complexity Lowest; easiest to validate More host mounts, permissions, services, and failure points

There is no universal performance number to attach to either design. Storage use and scrape load depend on target count, label cardinality, interval, retention, and metric volume. Choose the smallest stack that answers the monitoring question you actually have.

Troubleshooting by symptom

Prometheus exits immediately

  • Run docker compose logs prometheus and look for a YAML parse error, an unreadable mounted file, or an invalid command-line option.
  • Confirm the host path ./prometheus.yml exists. A typo can cause Docker to mount an unexpected directory or file type.
  • Run docker compose config to catch indentation and interpolation errors before restarting.

The target is down

  • Use the Compose service DNS name and internal port, such as cadvisor:8080; never substitute the host’s localhost.
  • Check that the target service is running with docker compose ps.
  • Read the target’s logs and test its endpoint from an appropriate container context.
  • Check the target’s port. A published host port is not required for Prometheus to reach a service on the shared Compose network.

The target is up but no historical data appears

  • Confirm the query’s time range includes the period after the target became healthy.
  • Check that the Prometheus data path is mounted at /prometheus.
  • Inspect available disk space and Prometheus logs for storage errors.
  • Verify that you did not recreate the project with docker compose down -v.

Port 9090, 8080, 6379, or 3000 is already in use

Change only the host side of the mapping, for example 127.0.0.1:19090:9090. Keep the container-side port unchanged unless you also change the target address inside the Compose network. Then open the new host port in your browser.

cAdvisor shows permission or missing-metric errors

Check the Linux host mounts, Docker runtime mode, and security policy. Rootless Docker and non-Linux environments can expose less host information than the standard privileged-style example expects. A running cAdvisor container is not proof that every container metric is available.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A reload appears to do nothing

Confirm that --web.enable-lifecycle is present, that the POST reached the Prometheus container, and that the edited file is the same file mounted at /etc/prometheus/prometheus.yml. Read the logs for a rejected configuration; Prometheus retains the last valid configuration when the new one fails validation.

Security and maintenance checklist

  • Bind development interfaces to 127.0.0.1 or place them behind controlled access.
  • Do not expose Prometheus, cAdvisor, Redis, or Grafana directly to the public internet without network controls and authentication where appropriate.
  • Mount configuration and rule files read-only.
  • Use explicit image tags in production and review upgrades before applying them.
  • Back up the Prometheus volume and test that a restore is possible.
  • Review labels and target counts as the stack grows; high-cardinality labels can increase storage and query cost.
  • Keep application metrics, cAdvisor metrics, and Docker-daemon metrics as separate monitoring paths so each alert identifies the correct layer.

End-to-end setup checklist

  1. Place compose.yml and prometheus.yml in one project directory.
  2. Mount the configuration at /etc/prometheus/prometheus.yml.
  3. Mount a named volume or bind mount at /prometheus.
  4. Use service DNS names such as prometheus:9090 and cadvisor:8080 in scrape jobs.
  5. Run docker compose config, then docker compose up -d.
  6. Check docker compose ps, container logs, the Prometheus interface, the targets page, and each target’s /metrics endpoint.
  7. Only after the basic stack is healthy, add cAdvisor, Grafana, exporters, rules, and additional application targets.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.