> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chronosphere.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Docker

> Per-container CPU, memory, block I/O, network, process and uptime metrics from a Docker daemon, plus the daemon's own container and image counts.

The Docker integration requires CXDOT Collector 1.4.0 or greater.

[Docker](https://www.docker.com/) is a platform for building and running applications
in containers.

Use the Docker integration with the Chronosphere XDOT Collector to collect
per-container resource metrics and container counts from Docker daemons running in
your environment.

The Docker integration supports Docker Engine 29.0 or greater.

## Supported telemetry types

The Docker integration supports these telemetry types:

| Type    | Supported |
| ------- | --------- |
| Logs    | No        |
| Metrics | Yes       |
| Traces  | No        |
| Events  | No        |

## Prerequisites

The Docker integration has the following prerequisites:

* Run Docker Engine as the container runtime on the nodes you collect from. Most
  Kubernetes clusters run containerd instead, which exposes no Docker daemon for this
  integration to read. To confirm which runtime your nodes run, run the following
  command and read the `CONTAINER-RUNTIME` column:

  ```shell theme={null}
  kubectl get nodes -o wide
  ```

* Run your nodes on Linux with cgroups v2, which most current distributions use. On a
  cgroups v1 node the integration still reports container and image counts and the
  per-container metrics the Docker daemon serves, but not the fields read from the
  node's cgroup tree: block I/O operation counts, memory reclaim events, kernel and
  swap memory, and open file descriptors.

* Make the Docker daemon reachable from the Collector, either through the node's Unix
  socket or over a TCP address the daemon listens on.

## Configure

The Docker integration is disabled by default. To configure the Docker integration,
follow these steps:

1. Enable the integration. For example, add the following to the `values.yaml` for your
   Helm chart:

   ```yaml theme={null}
   config:
     integrations:
       docker:
         enabled: true
   ```

   Each Collector reads the Docker daemon on its own node and reports the containers
   that daemon runs.

2. Allow the Collector to run as root. For example, add the following to the `values.yaml`
   for your Helm chart:

   ```yaml theme={null}
   nodeCollector:
     securityContext:
       runAsRoot: true
   ```

   `runAsRoot` is required for a Unix socket endpoint. `runAsRoot` is also required to emit
   `container.open_file_descriptors`.

   Leave `collect_open_file_descriptors` out of your `values.yaml` to keep the default, where
   the Collector reports the count when it can read it and skips it when it can't. Writing
   `collect_open_file_descriptors: true` makes the metric a requirement instead: the chart
   then refuses to deploy unless the Collector runs as root and reads a daemon on its own
   node.

3. Optional: Collect from a daemon at another address, such as one that listens on a TCP
   port. For example, add the following to the `values.yaml` for your Helm chart:

   ```yaml theme={null}
   config:
     integrations:
       docker:
         enabled: true
         endpoint: tcp://127.0.0.1:2375
   ```

   Open file descriptors are counted on the node the Collector runs on, so a daemon at any
   address other than a Unix socket, `localhost`, or `127.0.0.1` reports no
   `container.open_file_descriptors`. Don't set `collect_open_file_descriptors: true` for
   such an endpoint, because the chart then refuses to deploy.

4. Optional: Exclude the containers of images you don't want reported, such as
   short-lived build agents. For example, add the following to the `values.yaml` for
   your Helm chart:

   ```yaml theme={null}
   config:
     integrations:
       docker:
         enabled: true
         excluded_images:
           - registry.example.com/build-agents/*
   ```

### Validate

To validate the Docker integration, follow these steps:

1. In the Live Telemetry Analyzer, filter for `__name__=cxdot.integration.target.health`
   and `cxdot.integration.name=docker`. Confirm that the metric reports `1`, meaning the
   Collector reached the daemon. The `host.name` attribute identifies which node's
   daemon a reading describes.

2. In Metrics Explorer, run the following query:

   ```text theme={null}
   count by ("host.name") ({"container.cpu.utilization"})
   ```

   Confirm that the query returns one time series per node, each counting the containers
   running on that node.

### Troubleshooting

* Every other metric arrives, but `container.open_file_descriptors` is missing: Descriptor
  counts come from each process's own entry under `/proc`, on the node the containers run
  on, and only that process's own user and root can read them. A Collector that doesn't run
  as root reads none of them and reports no count for any container. A Collector reading a
  daemon on another host reports no count either, whatever it runs as, because the counts
  are on that host. For a daemon on the same node, set `runAsRoot` to `true`, as shown in
  Configure, or set `collect_open_file_descriptors` to `false` to stop collecting the
  metric.

For more information about diagnosing a failing integration, see
[Troubleshooting](https://docs.chronosphere.io/ingest/cxdot-collector/troubleshooting).

## Configuration reference

Configure one Docker integration instance with the following settings. In Helm values, place
these settings under `config.integrations.docker`. In a Collector configuration file, place them
under `cxdot.integrations.docker`.

### Optional settings

* **`enabled`**
  Type: `boolean`. Optional. Default: `true`.
  Whether to enable this configuration block. If true, the Collector runs the integration or
  capability. If false, the Collector doesn't run it.

* **`endpoint`**
  Type: `string`. Optional. Default: `unix:///var/run/docker.sock`.
  The Docker daemon the Collector reads container stats from. Either a Unix socket such as
  `unix:///var/run/docker.sock`, or a TCP address such as `tcp://host:2375`. The default
  connects to the daemon on the node the Collector runs on: directly in `host` mode, and in
  Kubernetes because the Helm chart mounts that node's socket into the Collector.

* **`api_version`**
  Type: `string`. Optional. Default: `1.44`.
  Docker Engine API version the Collector negotiates with the daemon. Must be at least 1.44, the
  oldest version Docker Engine 29 accepts, and the daemon must still support it.

* **`excluded_images`**
  Type: `array of string`. Optional. Default: `[]`.
  Images whose containers aren't reported. Each entry is a literal name, a glob, or a `/regex/`.

* **`collection_interval`**
  Type: `duration`. Optional. Default: `10s`.
  How often the Collector collects metrics from the Docker daemon.

* **`timeout`**
  Type: `duration`. Optional. Default: `10s`.
  Maximum time the Collector waits for the Docker daemon to respond during one collection. This
  value must not exceed `collection_interval`. If the deadline expires, that collection fails.

* **`collect_open_file_descriptors`**
  Type: `boolean`. Optional. Default: `true`.
  Whether to collect `container.open_file_descriptors`, the number of file descriptors open
  across all of a container's processes. If true, the Collector reports the metric. If false, it
  reports everything else and omits this one. The cost of this metric grows with the number of
  processes in the reported containers and the descriptors each has open, because every
  collection counts them again. Working out which container a process belongs to takes a read
  for every process on the node. That answer is cached and rechecked only every few dozen
  collections, so its cost is paid mostly on the first collection. Turning the metric off leaves
  every other field read under `root_path` collecting normally. The Collector can read
  descriptor counts only for a daemon on its own node, and only when it runs as root, because
  another user's open descriptors are readable only by root. In Kubernetes, set
  `nodeCollector.securityContext.runAsRoot` in the Helm chart. Left unset, the setting takes its
  default without making the metric a requirement: a count the Collector can't read is skipped,
  with a warning, rather than reported. Written out as `true`, it becomes a requirement: the
  Helm chart fails to render unless the daemon is on the same node as the Collector and
  `runAsRoot` is set.

* **`root_path`**
  Type: `string`. Optional.
  Root of the node file system when the Collector runs in a container with the node root
  bind-mounted, for example `/hostfs`. In Kubernetes the Helm chart mounts it and sets this
  value, so it rarely needs setting by hand. The Collector reads it for the per-container cgroup
  fields the Docker daemon's stats API doesn't report on cgroups v2: block I/O operation counts,
  memory reclaim events, kernel and swap memory, and open file descriptors. Those fields come
  from the node's cgroup tree instead. In `host` mode against a daemon on the same node, meaning
  a Unix socket or a `tcp://` endpoint on a loopback host such as `127.0.0.1` or `localhost`,
  the Collector runs on the node it reports on, so this value defaults to `/` and those fields
  are read from that node's own `/proc` and `/sys/fs/cgroup`. It stays unset for a `tcp://`
  endpoint naming another host, because these fields can't be collected without access to that
  host's file system. It also stays unset in `node` mode outside the Helm chart, where nothing
  mounts the node root or sets this value for you. When this value is unset, those fields aren't
  collected. Set it to `""` to switch the fields off where the default would otherwise apply.

* **`containers`**
  Type: `object`. Optional.
  Settings for Docker container metrics collection.

* **`containers.enabled`**
  Type: `boolean`. Optional. Default: `true`.
  Whether to enable this configuration block. If true, the Collector runs the integration or
  capability. If false, the Collector doesn't run it.


## Related topics

- [Install Core Agent in Docker](/ingest/pipeline/v2/fleets/agent/docker-install.md)
- [Installation prerequisites](/ingest/pipeline/v2/install/prereqs.md)
- [Standalone Collector installation to retrieve metrics](/ingest/metrics-traces/collector/install/standalone.md)
- [Install the Chronosphere Collector](/ingest/metrics-traces/collector/install.md)
- [Agent types](/ingest/pipeline/v2/fleets/agent.md)
