Docker Monitoring Guide
Learn what to monitor in Docker, investigate container failures, and connect container signals to reliable production host and service health checks.
Docker makes it easy to start a container. Operating one reliably requires seeing what happens when its process, dependencies, or host begin to fail.
Begin with the service, not the container
A container state is useful, but it is not the service outcome. A container can be marked running while its application is returning errors, waiting on a dependency, or unable to accept traffic. Start monitoring from the user-visible service and work inward.
For each workload, identify:
- the public endpoint or internal dependency it provides;
- the expected response, port, and protocol;
- the container or containers that implement it;
- persistent volumes, databases, queues, and external dependencies; and
- the host or nodes that supply CPU, memory, storage, and networking.
This map is the difference between collecting metrics and diagnosing an incident. If a site is slow, you need to determine whether the application is saturated, the database is delayed, the host is out of memory, or a reverse proxy cannot reach the container.
Pair container checks with website monitoring for public services. The outside-in check catches failures that a simple running status cannot.
Monitor the Docker lifecycle
At the container level, establish a baseline for what normal operation looks like. Review the lifecycle signals below and decide which ones need action.
Running state and restart behavior
A stopped container may be intentional during a deployment, so a single status change is not always an incident. Repeated restarts are more suspicious. They can indicate an application crash, a failed health check, an invalid environment variable, or a dependency that is unavailable at startup.
Use docker ps -a to see current and exited containers:
docker ps -a --format "table {{.Names}}\t{{.Status}}\t{{.Image}}"For a specific workload, inspect its exit details and restart policy:
docker inspect api --format \
'status={{.State.Status}} exit={{.State.ExitCode}} restarts={{.RestartCount}}'An exit code is evidence, not a diagnosis. Read application logs and correlate the time with deployment, configuration, and dependency changes. Do not repeatedly restart a failing container before preserving enough context to identify the cause.
Health checks
Docker health checks can distinguish a process that exists from one that is ready. They are useful when designed around a meaningful local condition, such as an HTTP readiness endpoint or a required process dependency.
Avoid health checks that are expensive, mutate data, or rely on an unrelated public path. A health check should run safely and predictably. It should also match the purpose of the restart behavior: an overly broad check can turn a brief dependency issue into a restart loop.
Inspect the health state with:
docker inspect --format '{{.State.Health.Status}}' apiNot every image defines a health check. Treat an absent health state as a configuration detail to review, not proof that the service is healthy.
Watch resource pressure on containers and hosts
Containers share the kernel and, unless constrained, compete for host resources. Monitoring only container CPU or memory can hide the condition that matters: the host may be exhausted even though no one container appears unusual.
Use a live view during investigation:
docker stats --no-streamLook at CPU use, memory use relative to limits, network traffic, and block I/O in the context of the workload. A high CPU value may be expected during a batch job; high CPU paired with rising request latency deserves closer attention.
On the host, monitor CPU, available memory, load, disk capacity, disk I/O, and network errors. Disk space matters for image layers, container logs, volumes, and temporary files. A full filesystem can prevent writes or stop new containers from starting even when the application itself has not changed.
For a practical host-level foundation, see Linux server monitoring. CloudStats also offers Docker container monitoring for bringing container signals alongside server metrics.
Treat logs as time-stamped evidence
Logs are often the fastest route from a restart count to a cause. Start with a bounded time range and preserve timestamps:
docker logs --since 30m --timestamps apiSearch for application errors, shutdown messages, connection timeouts, authentication failures, and out-of-memory messages. Then compare their timestamps with host metrics and recent changes.
Container logs need a retention plan. Unbounded log files can consume the same disk that the workload needs. Configure an appropriate logging approach for your environment, and ensure the operational team can reach the logs after a container exits.
Do not rely on logs alone. Quiet failures, blocked requests, and resource contention may produce little application output. Logs become more useful when a service check and host metrics establish the time window to investigate.
Add resource limits deliberately
Resource limits can prevent one workload from consuming all available memory or CPU, but arbitrary limits can make an otherwise healthy application fail. Establish a baseline first, then set limits based on expected peaks and test under representative load.
Pay close attention to memory. A process that exceeds a memory limit may be terminated by the kernel, causing a restart without a graceful application error. When investigating repeated exits, check both container state and host-level events.
Create alerts that point to action
Alerts should identify a condition, a scope, and an owner. Useful examples include a container that remains stopped unexpectedly, repeated restarts in a short period, sustained host disk pressure, or an unhealthy public endpoint.
Avoid alerting on every brief spike. Prefer conditions that persist long enough to require attention. CloudStats currently delivers alerts by email, so use an inbox that the responsible team monitors and document who investigates each category.
Use uptime monitoring for a separate confirmation that important endpoints remain reachable. It complements host and container data rather than replacing either.
Build a simple incident path
When a container-backed service fails, follow the same sequence:
- Confirm the user-facing symptom with an endpoint check.
- Identify the affected container, host, and recent deployment.
- Inspect status, restart count, health state, and recent logs.
- Compare the incident time with host CPU, memory, disk, and I/O pressure.
- Check dependencies before changing restart policies or limits.
- Verify recovery from the endpoint after the fix.
This path keeps investigation focused on evidence instead of assumptions. As the deployment grows, the same principles still apply: observe the service, the container, and the host together, then make alerts and runbooks reflect the way the system actually fails.
