Hi, I'm Daisy

Here is a place for my random musings!

Exploring the Docker API

In this post, we are going to explore Docker’s API and see what we can do with it!

Docker has become a popular solution for containerization needs and provide a lot of functionality surrounding run-of-the-mill tasks such as building images, running containers, and managing Docker on your machine. These are commonly done through Docker’s command line interface, which is actually a client that consumes a remote REST API provided by the Docker daemon.

The Docker REST API can replace the remote command line interface and you can pretty much do anything with Docker through it. By working with the remote API more directly, Docker can be leveraged by other tools and can be controlled from a number of environments instead of just from the shell.

It would be interesting to note that in the Docker universe, there are more APIs available, namely the Docker Registry API (which allows you to interact with the Docker image registry but does not have access to user accounts) and the Docker Hub API (which is a simple REST API that allows you to interact with the Docker Hub). This post will not go into detail for these APIs and will only focus on the API that works with the Docker daemon.

Docker was designed for automation and programmability and the Docker REST API is unusual in some ways because unlike most APIs, you don’t request data and get it back; it works more like a remote call. With Docker’s REST API, you can interact with Docker through code and create useful tooling. This post will explore how to get set up and some of the ways you can make use of this RESTful API.

Versioning

The API version gets updated when new features are added and it is backwards-compatible, which means that you don’t have to worry about updating your previous code unless you want to leverage the new features. When choosing an API version, keep in mind that the Docker client won’t know about new features or any deprecated endpoints in the Docker daemon if it is older than the daemon version. On the flip side, the Docker client could potentially make requests at endpoints that the Docker daemon is not aware of if it is newer than the daemon version.

Type docker version to see the highest API version supported by the client and the daemon:

Client:
Version: 18.03.1-ce
API version: 1.37
Go version: go1.9.5
Git commit: 9ee9f40
Built: Thu Apr 26 07:17:20 2018
OS/Arch: linux/amd64
Experimental: false
Orchestrator: swarm

Server:
Engine:
Version: 18.03.1-ce
API version: 1.37 (minimum version 1.12)
Go version: go1.9.5
Git commit: 9ee9f40
Built: Thu Apr 26 07:15:30 2018
OS/Arch: linux/amd64
Experimental: false

Setting Up the API

By default, the Docker daemon is configured to listen on a UNIX socket (which allows data transfer between processes on the same system) and the API can be accessed via this socket if you don’t want to tinker with the configuration files. In order to interact with the Docker REST API over a network, you can configure Docker (by editing it’s upstart file) to listen on a TCP/IP socket on a port on localhost. Once this is configured, you can use an HTTP client like cURL to interact with the Docker API.

Docker Remote API Basics

Here are some simple examples of how you can use Docker’s REST API with cURL to interact with images and containers:

To get a list of images: GET /images/json

$ curl http://localhost:5555/images/json

To list containers: GET /containers/json

$ curl http://localhost:5555/containers/json

To start a container: POST /containers/{id}/start

$ curl -X POST http://localhost:5555/containers/12345/start

To stop a container: POST /containers/{id}/stop

$ curl -X POST http://localhost:5555/containers/12345/stop

Docker-Specific API Use Cases

There are some issues that are quite specific to Docker which the Docker REST API could be used to help solve. For example, to avoid image and container buildup, you can create an automation with the API that cleans up stale images and stopped containers. This can be complemented by also checking disk space (which is directly available with some storage drivers).

It could also be useful to implement an auto-upgrade mechanism that periodically updates the images that you have locally by notifying when new images are available and restarting containers. For data stores, this requires extra care (i.e. making sure that the data is stored in a volume and that the volume is passed from the old to the new container).

Other API Use Cases

You can also use the Docker REST API to accomplish more generic tasks, such as automating the build process. While there already exists platforms that automatically builds from images and then pushes them to a Git repository, you could customize this whole process by implementing an automation that rebuilds each image on a daily basis to see if it has changed from the day before in order to detect if the build process depends on external sources. For example, if a package that the image uses changes overnight, then the daily build will also change even if the code repository didn’t change and this detection can be pretty useful.