Docker Container Monitoring in Uptime Kuma: Architecture and Implementation Guide
Uptime Kuma monitors Docker containers by connecting directly to the Docker daemon via Unix sockets or TCP endpoints, querying container state through the Docker API, and translating health status into UP, DOWN, or PENDING monitor states.
Uptime Kuma provides native Docker container monitoring that interfaces directly with the Docker daemon to track container health beyond simple process checks. This feature allows you to monitor container state, health check results, and runtime status through either local Unix sockets or remote TCP connections. Understanding how this mechanism works requires examining the interaction between the frontend Docker host management UI, the backend Docker helper utilities, and the monitor execution engine.
Architecture of Docker Container Monitoring
The Docker container monitoring system in Uptime Kuma operates across three distinct layers that handle host configuration, connection management, and health evaluation.
Frontend to Backend Communication
The configuration layer manages Docker host registration through Socket.io events. When you add a Docker host via the settings interface (src/components/settings/Docker.vue), the frontend emits the addDockerHost event handled by server/socket-handlers/docker-socket-handler.js. This handler persists host details—including socket paths or TCP endpoints—to the docker_host table via DockerHost.save.
Docker Host Helper Layer
The server/docker.js module provides core utilities for Docker daemon interaction. It handles connection testing through DockerHost.testDockerHost, which queries /containers/json?all=true to verify connectivity, and builds appropriate Axios configurations for both Unix socket (options.socketPath) and TCP (options.baseURL) connections. For TCP connections, it manages TLS certificate handling through DockerHost.getHttpsAgentOptions and URL normalization via DockerHost.patchDockerURL.
Monitor Execution Engine
When a monitor of type docker executes within server/model/monitor.js (lines 1414–1488), it loads the associated Docker host record and constructs an API request to GET /containers/<container-id>/json. The response parsing logic evaluates container state to determine monitor status.
Configuring Docker Hosts for Monitoring
Before creating container monitors, you must register Docker hosts through the Uptime Kuma settings interface.
Adding and Testing Docker Hosts
The system supports two connection types: Unix sockets for local daemons and TCP endpoints for remote hosts. To verify connectivity, the testDockerHost function attempts to list all containers:
// Example: Testing Docker host connectivity via Socket.io
socket.emit('testDockerHost', {
name: 'Production Docker Host',
dockerDaemon: 'tcp://192.168.1.100:2376',
dockerType: 'tcp'
}, (result) => {
if (result.ok) {
console.log('Connection successful. Containers found:', result.msg);
} else {
console.error('Test failed:', result.msg);
}
});
Connection Security and TLS
For TCP connections, Uptime Kuma constructs HTTPS agents with configurable TLS verification. The DockerHost.getHttpsAgentOptions method generates TLS configuration based on host settings, respecting the monitor's ignoreTls flag to handle self-signed certificates in development environments.
How Container Health Checks Execute
The core monitoring logic resides in server/model/monitor.js within the Docker-specific execution branch.
API Request Construction
During each monitoring interval, the system builds an Axios request targeting the Docker daemon. For socket connections, it sets socketPath to the Unix socket file path. For TCP connections, it configures baseURL and attaches the HTTPS agent:
// Simplified excerpt from Monitor.start (server/model/monitor.js)
const dockerHost = await R.load("docker_host", this.docker_host);
const options = {
url: `/containers/${this.docker_container}/json`,
timeout: this.interval * 1000 * 0.8,
headers: { Accept: '*/*' }
};
if (dockerHost._dockerType === "socket") {
options.socketPath = dockerHost._dockerDaemon;
} else {
options.baseURL = DockerHost.patchDockerURL(dockerHost._dockerDaemon);
options.httpsAgent = new https.Agent(
await DockerHost.getHttpsAgentOptions(dockerHost._dockerType, options.baseURL)
);
}
const res = await axios.request(options);
State Evaluation Logic
The monitor parses the JSON response from the Docker API to determine container status using the following rules:
- Running State: If
res.data.State.Runningistrueand no health check is configured, the monitor reports UP - Paused State: If
State.Pausedis true, the monitor throws an error and reports DOWN - Restarting State: If
State.Restartingis true, the monitor sets status to PENDING with a restart notification - Health Check Results: When
State.Healthexists:healthy→ UPunhealthy→ DOWN- Any other status (starting, etc.) → PENDING
Database Schema and Monitor Configuration
Docker monitors require specific database entries linking them to Docker hosts. The monitor table stores the container identifier in docker_container and references the host via docker_host:
INSERT INTO monitor (
name, type, docker_host, docker_container, interval, user_id
) VALUES (
'Nginx Container',
'docker',
1, -- Reference to docker_host.id
'nginx-proxy', -- Container name or ID
60,
1
);
Summary
- Uptime Kuma implements Docker container monitoring through direct Docker API communication using Axios, supporting both Unix sockets and TCP endpoints with TLS authentication
- The
server/docker.jsmodule provides host management utilities includingDockerHost.testDockerHostfor connectivity verification and TLS agent configuration - Monitor execution occurs in
server/model/monitor.js(lines 1414–1488), where the system queries/containers/<id>/jsonand evaluatesState.Running,State.Paused, andState.Healthto determine status - Health status mapping follows specific rules: running containers without health checks report UP, paused containers report DOWN, restarting containers report PENDING, and explicit health checks override the running state
- Configuration persists in the
docker_hosttable, managed through Socket.io handlers inserver/socket-handlers/docker-socket-handler.js
Frequently Asked Questions
Does Uptime Kuma require the Docker socket to be mounted for container monitoring?
Yes. To monitor Docker containers, Uptime Kuma must access the Docker daemon either through a mounted Unix socket (typically /var/run/docker.sock) or via a TCP endpoint. When using the socket method, ensure the Uptime Kuma container has the socket volume-mounted with appropriate permissions. For remote hosts, configure TCP access in the Docker daemon settings and register the endpoint in Uptime Kuma's Docker host settings.
What is the difference between a container being "Running" and "Healthy" in Uptime Kuma?
A container in "Running" state has an active process but may not have completed startup or passed application-specific health checks. Uptime Kuma reports these as UP unless the container defines a HEALTHCHECK instruction in its Dockerfile. When health checks are configured, Uptime Kuma prioritizes the State.Health.Status field: "healthy" means UP, "unhealthy" means DOWN, and intermediate states like "starting" result in PENDING status.
How does Uptime Kuma handle Docker daemon connection failures?
If the Docker daemon is unreachable during a monitoring interval, the Axios request in server/model/monitor.js throws a connection error that propagates to the monitor's heartbeat logic. This results in a DOWN status for the monitor, with the error message containing the specific connection failure details (timeout, ECONNREFUSED, or TLS errors). The system does not cache previous states; each check requires successful API communication.
Can Uptime Kuma monitor containers on multiple remote Docker hosts simultaneously?
Yes. Uptime Kuma supports configuring multiple Docker hosts through the docker_host table, each with distinct connection parameters. You create separate monitor records for each container, specifying the appropriate docker_host ID for each. The monitor execution engine loads the specific host configuration via R.load("docker_host", this.docker_host), allowing simultaneous monitoring of containers across different servers or clusters.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →