Using curl and the UNIX socket to talk to the Docker API

Though it is usually hidden behind the docker client binary or other tools, direct communication with the docker API (REST-ish) is sometimes needed in order to debug, understand proper usage, or simply to learn more about the internals of how Docker works. By default the Docker daemon listens on a UNIX socket located at /var/run/docker.sock for incoming HTTP requests, but also can be exposed on a TCP port. In most cases, however, the TCP port exposing the Docker API is secured with TLS (otherwise anyone with access to the API could quite trivially root the box where Docker is running) and accessing TLS-secured endpoints using curl can be a real pain.

Communication with UNIX sockets was added in cURL version 7.40, but many Linux distributions come with and/or have an older version in their package manager. If our host distribution’s package version is out of date, we might consider using a container for the proper curl version. However, many of the library images have the same issue. Out of the box in a Debian Jessie container at the time of writing, for instance, we get a slightly older version:

We could build an image to compile curl from source and use that, but the resulting image would likely be several hundred megabytes in size. That is very expensive for a simple image just to run some curl commands on a socket.

Building a small image to run the right curl

Luckily, the very exciting Alpine Linux project has both a very small disk footprint, and a version of curl which is sufficiently up-to-date in their package manager. Consequently a small Dockerfile such as this:

Will produce a resulting image which is only about 10MB in size, but contains the curl command we need. I have such an image hosted at nathanleclaire/curl (or you could build your own with the Dockerfile above), so to run curl on the UNIX socket simply mount the socket in to a container based on this image:

You could make other images which inherit this small base image and add more fancy stuff like jq, but for simple debugging purposes a small Alpine-based image works quite well.


I hope this helps in making communicating with the Docker UNIX socket a bit easier.

Until next time, stay sassy Internet.

  • Nathan
I want to help you become an elite engineer. Subscribe to follow my work with containers, observability, and languages like Go, Rust, and Python on Gumroad.

If you find a mistake or issue in this article, please fix it and submit a pull request on Github (must be signed in to your GitHub account).

I offer a bounty of one coffee, beer, or tea for each pull request that gets merged in. :) Make sure to cc @nathanleclaire in the PR.