Most guides to Docker monitoring start by listing tools. That ordering is backwards: the tools only make sense once you know which of the six independent signals you actually need, because almost none of them cover more than two.
This guide covers what Docker monitoring means in practice, the four architectures used to implement it, an honest comparison of ten tools, and a decision path for picking one.
What Docker monitoring actually covers
“Is my container up?” is a single question with six unrelated answers. A container can be running and useless. A service can respond perfectly while its certificate expires in two days. Treating these as one problem is how teams end up with five dashboards.
Container lifecycle. Whether a container exists, what state it is in, how many times it has restarted, and what exit code it died with. A crash-looping container often reports as “running” if you sample at the wrong moment — restart count is the signal that matters, not state.
Resource usage. CPU, memory, network and block I/O per container, plus the same for the host. The useful part is not the instantaneous number but the trend: a memory figure means nothing without knowing whether it has been climbing for six hours.
Service reachability. Whether the thing inside the container answers. A container can be healthy at the runtime level and return 500 on every request. Only an HTTP or TCP probe from outside tells you that, and only content assertions tell you the response is correct rather than merely present.
TLS certificates. Expiry dates for every domain you terminate. This is the outage that is entirely predictable and still happens constantly, because the expiry lives in a different system from the one being monitored.
Scheduled jobs. Whether your backups, cleanups and cron containers actually finished. Nothing detects a silent absence: a cron that stopped firing produces no error, no log line and no alert. Detecting it requires the inverse pattern — a heartbeat URL the job calls on success, with an alarm when the call does not arrive.
Image drift. The distance between the image tag you are running and what has been published upstream, including whether the newer image fixes a known CVE. :latest does not update itself.
Six signals. Now the architectures.
The four architectures
Exporters plus a time-series database
The Prometheus model. Small processes expose metrics on an HTTP endpoint, a central server scrapes them on an interval and stores them, a separate component evaluates alert rules, and a visualisation layer queries the store.
For Docker specifically that usually means Prometheus, cAdvisor for container metrics, node-exporter for host metrics, Alertmanager for routing, Blackbox exporter for endpoint probes, and Grafana on top. Six components before the first dashboard.
The payoff is real: PromQL is genuinely powerful, retention is yours to configure, and the ecosystem covers everything. The cost is equally real — you are operating a monitoring stack in addition to the stack you wanted to monitor, and the storage layer is the part that pages you at 3 a.m.
An agent per host
A small binary runs on every machine, collects metrics locally and either serves a UI or ships data to a hub. Netdata, Beszel and Zabbix work this way.
The strength is depth of host-level detail and per-second granularity. The cost is fleet management: an agent per host means a deployment, an upgrade path and a firewall rule per host. It scales fine technically and adds friction operationally.
Reading the Docker socket
One container mounts /var/run/docker.sock and asks the Docker daemon what exists. No exporters, no per-container instrumentation, no agent on every machine. Containers are discovered as they start; labels on a service configure how it is monitored.
This is by far the lightest option — implementations typically sit in tens of megabytes of RAM — and it is the only one where adding a service to your docker-compose.yml is the entire configuration step.
The trade-off is access. The Docker socket is the Docker API: read-only mounting protects the file, not the API behind it. Anything that reads the socket should sit behind authentication, and in production the socket should be reached through a socket proxy that whitelists endpoints.
Hosted SaaS
Datadog, New Relic, Dynatrace. An agent ships everything to a vendor who owns storage, correlation and alerting.
You get breadth no self-hosted tool matches, and APM, logs and traces in the same place. You also get per-host pricing that scales linearly with your fleet, your infrastructure telemetry sitting on someone else’s servers, and — for most teams that leave — a bill that grew faster than the fleet did.
Ten tools, honestly compared
No tool here is bad. They target different problems, and the mismatch between what a tool does and what a team needs is what causes the tool sprawl this guide opened with.
| Tool | Architecture | Primary strength | Does not cover | Licence |
|---|---|---|---|---|
| Prometheus + Grafana | Exporters + TSDB | PromQL, retention, ecosystem | Turnkey anything; ~6 components to assemble | Apache-2.0 / AGPL-3.0 |
| Netdata | Agent per host | Per-second granularity, deep host metrics | Cron heartbeats; agent on every host | GPL-3.0 |
| Uptime Kuma | Prober | Uptime checks, 90+ notification channels, status page | Container resources, image drift | MIT |
| Beszel | Hub + agent | Very light host and container resource stats | Endpoint probing, certs, crons, updates | MIT |
| Dozzle | Socket reader | Real-time container logs, excellent UI | Metrics, alerting, probing — it is a log viewer | MIT |
| cAdvisor | Exporter | Accurate per-container resource metrics | Storage, alerting, UI — it is a data source | Apache-2.0 |
| Glances | Agent | Terminal-first host overview | Alerting, history, multi-host at scale | LGPL-3.0 |
| Portainer | Socket reader | Container management and deployment | Monitoring depth; it manages more than it watches | Zlib |
| Zabbix | Agent + server | Enterprise breadth, deep alerting model | Simplicity; substantial setup and schema | AGPL-3.0 |
| Datadog | SaaS agent | Breadth, APM, logs, traces, correlation | Self-hosting; cost scales per host | Commercial |
| Maintenant | Socket reader | All six signals in one container, 20 MB RAM | Log aggregation, APM, distributed tracing | AGPL-3.0 |
Two observations from that table.
Every row that is strong on one signal is silent on four others. That is not a flaw in those tools — Dozzle is a log viewer and is excellent at it. It is why the median self-hoster runs Uptime Kuma for HTTP, Healthchecks for crons, Netdata or Beszel for resources, a certificate script, and a fifth thing for image updates.
And the licence column matters more than it looks. AGPL-3.0 obliges you to publish modifications if you offer the software as a network service; MIT does not. If you are embedding a monitoring tool in a product you sell, read the licence before the feature list.
Choosing, by scenario
A homelab, one host, a dozen containers. You want zero-configuration auto-discovery and a single container. Any of Beszel, Dozzle or Maintenant fit, depending on whether you care about resources, logs, or all six signals. Prometheus here is a hobby, not a solution.
Production, 2 to 20 hosts, small team. Fleet management is now the deciding factor. A socket reader with a lightweight agent per remote host beats an exporter stack you have to operate. You need alert routing that reaches where the team actually is, and a status page for the people asking whether it is down.
An agency or MSP, several clients, one fleet. The deciding factors move from technical to contractual: a licence that covers infrastructure you run for someone else, alerting that escalates, and a status page the client can read. See Docker monitoring for agencies and MSPs.
Production, 50+ hosts, dedicated platform team. Prometheus earns its complexity here. You have people who know PromQL, retention requirements that need tuning, and enough scale that the operational overhead amortises. Pair it with Grafana and Alertmanager and accept that the stack is a system you own.
Regulated, air-gapped, or sovereignty-constrained. Self-hosted is the requirement, not the preference. Prefer a single binary with no external dependencies: fewer moving parts is fewer things to certify.
Already paying for Datadog and reviewing the bill. The technical question is which of the six signals you actually use. Teams that use APM and distributed tracing have a genuinely hard migration. Teams that mostly look at infrastructure dashboards usually discover they are paying platform prices for container metrics and uptime checks.
Monitoring Docker in one container
Maintenant is the socket-reader in the table above, built around the observation that the six signals belong together. It is a single Go binary with an embedded Vue frontend and SQLite, running at about 20 MB of RAM at idle, AGPL-3.0.
services:
maintenant:
image: ghcr.io/kolapsis/maintenant:latest
ports:
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- maintenant-data:/data
restart: unless-stopped
volumes:
maintenant-data:
docker compose up -d, open port 8080, and every running container is already discovered. No agent, no exporter, no scrape config, no database to provision.
Two warnings that apply to this and to every socket-reading tool. Publishing 8080 on all interfaces exposes the admin API to anything that can reach the host — put it behind a reverse proxy that authenticates. And the :ro flag protects the socket file, not the Docker API behind it, so in production reach Docker through a socket proxy.
Endpoint checks, heartbeats and certificates are configured from the UI or with Docker labels in your compose file, which keeps the configuration versioned alongside the service it describes. The 2-minute walkthrough covers the first run in detail.
Where to go next
If you arrived here comparing against a specific tool, the honest comparisons are more useful than this overview:
- Alternative to Prometheus + Grafana — when the stack is more machinery than the problem needs
- Alternative to Netdata — per-second host metrics versus unified coverage
- Alternative to Uptime Kuma — uptime probing versus container awareness
- Alternative to Beszel — the closest comparison, and where the two diverge
- Alternative to Datadog — what self-hosting actually costs you in features
And if you run Swarm, the orchestrator changes the problem: monitoring Docker Swarm covers services, tasks and node state rather than plain containers.