Features Comparison Pricing Alternatives Blog Docs Français GitHub
dockerdocker-composemonitoringzero-configtutorial

Monitor Docker Compose Without Writing Config Files

· 3 min read ·Benjamin Touchard

Every monitoring tool asks you to write config files. Prometheus needs prometheus.yml. Grafana needs datasource configs. Alertmanager needs routing rules. Even Uptime Kuma needs you to click through a web UI to add each monitor manually.

What if your monitoring tool just… figured it out?

The Config File Problem

Config files create three problems:

  1. Drift — your monitoring config drifts from your actual infrastructure. You add a new service and forget to add a monitor. You rename a container and the old alert keeps firing.
  2. Duplication — your service is defined in docker-compose.yml, then again in prometheus.yml, then again in Grafana. Three places to update for every change.
  3. Learning curve — every tool has its own config format. PromQL, YAML with specific schemas, JSON datasources. Each one is another thing to learn.

The Label-Based Approach

Docker labels are metadata attached to your containers. They are defined in your docker-compose.yml — the same file where your services live. No separate config files.

Maintenant reads Docker labels to configure monitoring:

services:
  api:
    image: myapp:latest
    labels:
      maintenant.endpoint.http: "http://api:3000/health"
      maintenant.endpoint.interval: "30s"
      maintenant.endpoint.http.expected-status: "200"

  postgres:
    image: postgres:16
    labels:
      maintenant.endpoint.tcp: "postgres:5432"

  redis:
    image: redis:7-alpine
    labels:
      maintenant.endpoint.tcp: "redis:6379"

Your monitoring configuration lives alongside your service definition. When you add a new service, the monitoring is right there. When you remove a service, the monitoring goes with it. No drift.

What Gets Auto-Discovered (Zero Config)

Even without any labels, Maintenant auto-discovers:

  • All containers — states, health checks, restart loops, exit codes
  • Compose projects — containers grouped by their com.docker.compose.project label
  • SSL certificates — auto-detected on all HTTPS endpoints you monitor
  • System resources — CPU, RAM, network, disk per container and per host
  • Available updates — OCI digest comparison for all running images

Container auto-discovery — no config needed

What You Configure via Labels

Labels add monitoring that requires knowing what to check:

HTTP endpoint checks

labels:
  maintenant.endpoint.http: "https://api.example.com/health"
  maintenant.endpoint.interval: "15s"
  maintenant.endpoint.http.expected-status: "200"

HTTP/TCP endpoint monitoring — latency, status codes

TCP connectivity checks

labels:
  maintenant.endpoint.tcp: "postgres:5432"

Alert severity

labels:
  maintenant.alert.severity: "critical"

A Complete Example

Here is a full Docker Compose stack with monitoring built in — zero external config files:

services:
  traefik:
    image: traefik:v3
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro

  api:
    image: myapp:latest
    labels:
      maintenant.endpoint.http: "http://api:3000/health"
      maintenant.endpoint.interval: "15s"

  worker:
    image: myapp:latest
    command: worker

  postgres:
    image: postgres:16
    labels:
      maintenant.endpoint.tcp: "postgres:5432"
    volumes:
      - pgdata:/var/lib/postgresql/data

  redis:
    image: redis:7-alpine
    labels:
      maintenant.endpoint.tcp: "redis:6379"

  maintenant:
    image: ghcr.io/kolapsis/maintenant:latest
    ports:
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /proc:/host/proc:ro
      - maintenant-data:/data
    environment:
      MAINTENANT_ADDR: "0.0.0.0:8080"
      MAINTENANT_DB: "/data/maintenant.db"
    restart: unless-stopped

volumes:
  pgdata:
  maintenant-data:
docker compose up -d

That is it. Six services monitored. Zero config files written. The dashboard shows everything:

Unified dashboard — all services monitored via labels

Compared to the Config File Approach

Prometheus + GrafanaMaintenant
Service definitiondocker-compose.ymldocker-compose.yml
Monitoring configprometheus.yml + scrape configsDocker labels (same file)
Dashboard configGrafana JSON + datasourcesAuto-generated
Alert configalertmanager.yml + rules filesBuilt-in defaults + labels
Config files total3-50
Config locations3-5 separate files1 file (docker-compose.yml)

Why This Matters

Monitoring-as-code should not mean “more code files to maintain.” It should mean “monitoring that lives where your services live.”

Docker labels achieve this. Your monitoring configuration is:

  • Versioned — it is in your docker-compose.yml, which is in your git repo
  • Colocated — next to the service it monitors, not in a separate directory
  • Atomic — when you remove a service, its monitoring goes with it
  • Discoverable — anyone reading the compose file sees what is monitored

No prometheus.yml. No grafana.ini. No alertmanager.yml. Just your docker-compose.yml with a few extra labels.

Install Maintenant →

← Maintenant vs Uptime Kuma: An Honest Comparison Monitor Your Docker Stack in 2 Minutes →

Ready to try Maintenant ?

One container, zero config. Full monitoring in 30 seconds.

Install