How to get started with the Docker Engine API

0
18


Docker Engine exposes a REST API that you can use to control your containers without the docker CLI. The API exposes equivalent functionality through HTTP network calls. You can script common Docker operations using your favorite programming language or remotely control one of your hosts. The CLI internally relies on the same API to provide its built-in commands.

In this article, we’ll go through the basics of enabling and using the API. If you have a specific use case in mind, refer to the API reference documentation to identify the endpoints you need.

Enabling the Docker Engine API

The API is integrated with the Docker Engine. Any running Docker host is already set up to handle API interactions. To expose the service, you must bind the Docker daemon to a TCP socket, as well as, or instead of, the default Unix socket. beginning dockerd with the -H flag to specify the sockets to listen on:

sudo dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375

This command exposes the API on port 2375. The default Unix socket is preserved, so the Docker CLI will continue to work without any reconfiguration. Port 2375 is used for Docker by convention; feel free to change it to suit your environment.

You can make Docker always start with this setting by editing your systemd service configuration file. Edit or create /etc/systemd/system/docker.service.d/options.conffind the ExecStart and modify it to include your additional flags:

[Service]
ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375

recharge your systemd settings to apply the change:

sudo systemctl daemon-reload

You are now ready to interact with the Docker Engine API at 127.0.0.1:2375.

A note on security

The above steps expose the API without any protection. Anyone with access to port 2375 on your host can send arbitrary commands to the Docker daemon, start new containers, fill your disk with images, or destroy existing workloads.

You should configure your firewall to block connections to the port unless you are intentionally exposing Docker on your network. If you want to enable remote access, you must configure TLS so that the daemon’s socket limits access to authenticated clients.

When TLS is enabled, you will need to install your daemon’s certificate authority on each of your clients. You will need to provide the client certificate and client key with each request you make. The steps to follow will depend on the tool you are using. Here is an example for curl:

curl https://127.0.0.1:2375/v1.41/containers/json --cert client-cert.pem --key client-key.pem

You may not need to bind a TCP socket at all depending on your use case. If your client supports Unix sockets, you can use the existing Docker socket to make your connections:

curl --unix-socket /var/run/docker.sock http://localhost/v1.41/containers

This may be a safer option than risking unintentional exposure of a TCP socket.

API Usage

The API uses versioned endpoints so you can pin specific versions of request and response formats. You must indicate the version you are using at the beginning of each endpoint URL. v1.41 is the latest version present in production builds of Docker at the time of writing.

http://127.0.0.1:2375/v1.41

API endpoints are grouped into REST functional units. These map to fundamental Docker object types, such as containers, images, and volumes. You can usually find the APIs for a specific object type within the base URL that starts with its name:

# APIs related to container operations
http://127.0.0.1:2375/v1.41/containers

The API uses JSON for all data exchanges with your HTTP client. Endpoints accept JSON request bodies and issue JSON responses in return. This should simplify data handling within your applications, since you can use the JSON library included with your programming environment. tools like jq can be used to condense, filter and classify responses if you are experimenting on your terminal.

Common endpoints

Since the API replicates the functionality of the Docker CLI, there are too many possible endpoints to cover them all here. Instead, we will demonstrate some of the more commonly used options related to Docker’s core functionality.

Container List

The complete list of containers on the host can be obtained from the /containers/json final point:

curl http://127.0.0.1:2375/v1.41/containers/json

By default, it shows only running containers. Add all=true to the query string to also include stopped containers. Limit the total number of containers returned with the limit parameter, like limit=10. Only the 10 most recently created containers will be included.

There are several different filters available to narrow down the list to containers with particular attributes. These are set with the following syntax:

curl http://127.0.0.1:2375/v1.41/containers/json?filters={"name":"demo"}

This URL returns the information associated with the demo container. Other filters can be expressed in a similar way, such as {"status":["running","paused"]} to get running and paused containers or {"health=["healthy"]} only for healthy containers.

Starting a new container

Starting a container is a two stage process when using the API. You need to create the container first, then start it in a separate API call.

Create your container by doing a POST request to the /containers/create endpoint This needs a JSON body with fields that correspond to the flags accepted by the docker run CLI command.

Here is a minimal example of how to create a container:

curl http://127.0.0.1:2375/v1.41/containers/create 
    -X POST 
    -H "Content-Type: application/json" 
    -d '{"Image": "example-image:latest"}'

The JSON response will include the ID of the new container and any warnings from its creation. Send the ID in a call to /containers/:id/start final point:

curl http://127.0.0.1:2375/v1.41/containers/abc123/start -X POST

The container will now run on the Docker host.

container cleaning

Remove stopped containers by issuing a POST apply to the /containers/prune final point:

curl http://127.0.0.1:2375/v1.41/containers/prune -X POST

A JSON response will be issued to you with ContainersDeleted Y SpaceReclaimed fields. ContainersDeleted is an array of the container IDs that were successfully removed. SpaceReclaimed tells you the total freed storage space in bytes.

This endpoint accepts two query string parameters to restrict the operation. the until The parameter limits the deletion to containers created before a certain time, such as until=10m either until=2022-03-01. the label option filters to containers with or without given labels; adjustment label=demo=example will only remove the containers with the demo=example label.

List of images

the /images/json endpoint is used to list the images stored on the Docker host:

curl http://127.0.0.1:2375/v1.41/images/json

You can use filters to modify the content of the response. These are provided as a JSON object in the filters query string parameter, similar to the container list API. One notable option is reference which selects the image with a given tag: filters={"reference":"hello-world:latest"}.

buildings images

You can use the API to create new Docker images from Dockerfiles. the /build endpoint should be sent a tar File, Archive. The content of this file will be used as the build context for the image. The file must include a Dockerfile that contains the instructions for the build.

cat context.tar | curl http://127.0.0.1:2375/v1.41/build?t=example-image:latest -X POST

The above command will send context.tar to the Docker daemon and create an image using the Dockerfile within. The image will be tagged as example-image:latest and stored on the Docker host.

This endpoint accepts many additional query string parameters that match the functionality of the docker build CLI. These include dockerfile=path/to/dockerfileto specify the path to the build context’s Dockerfile, rm=truewhich removes the intermediate containers created by the build, and pull=true to test and acquire updated versions of the images referenced by the Dockerfile.

The API requires your client to stay connected until the build is complete. The build will abort if the network goes down and the connection is closed.

Daemon event log listing

the /events The API returns data from the daemon’s event log which can also be accessed with the docker events CLI command. This endpoint streams events in real time as they occur.

curl http://127.0.0.1:2375/v1.41/events

Several different types of events are exposed, including container creations, image tags, volume mounts, and network changes. You can filter to a specific type of event using the type field of filters query parameter:

# Only get container events
curl http://127.0.0.1:2375/v1.41/events?filters={'type':'container'}

It is also possible to restrict events related to a specific object:

# Get events pertaining to the container with ID abc123
curl http://127.0.0.1:2375/v1.41/events?filters={'container':'id'}

Two other query string parameters, since Y untilallows you to specify a timestamp range to display historical events within.

Get system information

The Docker Engine API can be used to get information about the physical host it is running on:

curl http://127.0.0.1:2375/v1.41/info

This endpoint provides extensive details describing the current state and configuration of the Docker daemon and host. Fields in the response include counts of the number of running, paused, and stopped containers, the path to the Docker installation directory, hardware and operating system details, and the Swarm configuration of the server when it is operating within a server. cluster.

conclusion

The Docker Engine API gives you a way to send commands to your host’s Docker daemon over HTTP. This makes it easy to script programmatic interactions without relying on specific Docker CLI behaviors. The API can also be used to remotely manage your Docker servers for better monitoring and easier maintenance.

While calling the API should be straightforward, you should pay attention to the security protections around your TCP socket. Avoid exposing the socket on your network unless it is protected with TLS so that only approved clients can connect. Skipping this extra configuration step could be costly if an attacker discovers your daemon instance and starts issuing commands.

You can make it even easier to use the API within your own applications by adopting one of the SDKs. An official or community-provided option is available for all popular programming languages, including C, C#, C++, Go, Java, NodeJS, PHP, Python, and Ruby. SDKs wrap API endpoints in convenient classes and functions to call from your code, reducing the amount of iteration required to interact with a Docker installation.