Collect Docker metrics with Prometheus - via /var/run/docker.sock?

I would like to fetch the Docker Prometheus metrics via /var/run/docker.sock. It seems a lot easier to pass the docker.sock to a Docker Swarm container than to wrangle with host’s localhost to give a container access to the metrics of the host.

The docs state “To configure the Docker daemon as a Prometheus target, you need to specify the metrics-address”:

# /etc/docker/daemon.json
  "metrics-addr" : "",
  "experimental" : true

I expected the metrics to be automatically available via /var/run/docker.sock at path /metrics, but this seems not the case:

$ curl --unix-socket /var/run/docker.sock http://localhost/metrics
{"message":"page not found"}

Is it possible to have the /metrics available on docker.sock, in addition to the regular Docker API? How can this be configured?

Turns out that having the metrics on the Docker API socket is an open issue since 2017.

Is it possible to make metrics available at a different path like /var/run/docker.metrics.sock instead of using an IP address with metrics-addr?

Swarm docs says you should avoid using bind mounts: Deploy services to a swarm | Docker Documentation
But if you really want to do this, you can turn a tcp socket into a unix socket with socat.

This is just a simple example and someone with more swarm experience may correct me if I used the parameters wrong. You can also use a swarm stack file instead.

Run socat on every swarm node to create unix sockets

docker service create \
  -d \
  --name docker-metrics \
  --mode global \
  --mount type=bind,src=/var/run/docker-socat,dst=/var/run/docker-socat \
  --network host \
  alpine/socat \
  UNIX-LISTEN:/var/run/docker-socat/metrics.sock,reuseaddr,fork TCP:

Test the unix socket with curl in a container.

docker run --rm -it -v /var/run/docker-socat/metrics.sock:/tmp/metrics.sock --user root curlimages/curl --unix-socket /tmp/metrics.sock http://localhost/metrics


Since /var/run/docker-socat will not exist after reboot as it is in a temporary folder, you could use /var/docker-socat instead:

mkdir -p /var/docker-socat
docker service create \
  -d \
  --name docker-metrics \
  --mode global \
  --mount type=bind,src=/var/docker-socat,dst=/var/docker-socat \
  --network host \
  alpine/socat \
  UNIX-LISTEN:/var/docker-socat/metrics.sock,reuseaddr,fork TCP:
docker run --rm -it -v /var/docker-socat/metrics.sock:/tmp/metrics.sock --user root curlimages/curl --unix-socket /tmp/metrics.sock http://localhost/metrics