1. Overview
In this tutorial, we’ll explore how to list images in a remote Docker registry and how to fetch tags for an image.
This is useful for finding out what versions of a particular image are available in a registry and deciding which one to use.
2. Docker Registry API
A Docker registry provides an API to interact with the registry. This API contains the various endpoints used in the background by the Docker CLI to perform various tasks like pulling, pushing, and tagging images.
We can also use these endpoints directly to interact with a registry without using the Docker CLI.
Let’s look at the format of an endpoint of the registry API:
/<api-version>/<repository-name>/<resource>/<params>
Let’s examine the different components of this endpoint:
- API version – the version of the API. For example, the current version is v2*.*
- Repository(image) name – The name of the image. The name also can contain a path separated by slashes if it is a nested repository. For example, /ubuntu/nginx or /redis.
- Resource – The subdivision of the API we want to interact with. For example, manifests will work with manifests of a particular image.
- Parameters – These are optional parameters that can be used to further refine the operation. For example, manifests/latest will fetch the manifest for the latest tag.
Based on the above rules, below is a concrete example of an endpoint:
GET /v2/ubuntu/nginx/manifests/latest
3. Docker Registry API V2
At the time of writing, V2 is the current version of the Registry API. Let’s explore how to use it to list images and tags from a remote registry.
Let’s assume we have a registry deployed at the URL https://my-registry.io. We’ll use curl to execute the HTTP requests.
3.1. Listing Images
To list images in a registry, we can use the _/catalog endpoint:
$ curl -X GET my-registry.io/v2/_catalog
{"repositories":["centos","ubuntu"]}
We should note that authentication may be required to access certain repositories if it has been enabled. In such cases, we can pass in the username and password as parameters to the curl command using the -u option.
$ curl -u user:password -X GET my-registry.io/v2/_catalog
{"repositories":["centos","ubuntu"]}
3.2. Paginated Listing Images
Sometimes, a registry will have a large number of images. In such cases, we can add an n=
$ curl -X GET my-registry.io/v2/_catalog?n=1
{"repositories":["centos"]}
The response contains only the first image now.
We can use the response to the first request to get the next page of results. This needs two changes to the curl command:
- A l**ast parameter to the _/catalog endpoint containing the last image name returned in the previous request.
- A header linking the new request to the previous one. The header has the format below:
Link: <my-registry.io/v2/_catalog?n=1&last=centos>; rel="next"
The brackets around the URL are required. The URL is the same as the URL of the new request. A rel=”next” header indicates that the new request is a continuation of the previous one as per RFC 5988.
So let’s make the next request:
$ curl -H 'Link: <my-registry.io/v2/_catalog?n=1&last=centos>; rel="next"' -X GET "my-registry.io/v2/_catalog?n=1&last=centos"
{"repositories":["ubuntu"]}
The response returns the next page of results containing one image.
3.3. Listing Tags
To list the tags of an image, we can use the /tags/list endpoint:
$ curl -X GET my-registry.io/v2/ubuntu/tags/list
{"name":"ubuntu","tags":["latest","16.04"]}
The response contains the name of the image and an array of the tags associated with it.
4. Docker Registry API V1
Registry API v1 was deprecated in Docker 17.06 and removed in Docker 17.12. However, if we come across a registry hosted before the deprecation, we can use the v1 API. Let’s explore how our requests change in this case.
4.1. Listing Images
There is no direct endpoint to list images in v1. Instead, we can use the docker search command to search for images containing a given string:
$ docker search my-registry.io/centos
This returns a list of images that contain the string “centos” in their name or description.
If we do not specify the registry, the search will be performed in the default registry. The default repository is the Docker Hub repository.
For example, the below image shows the output when we search for the term “ubuntu” without specifying any repository.
4.2. Listing Tags
The method to list tags is similar to the v2 API. However, the output is different in this case:
$ curl -X GET https://registry.hub.docker.com/v1/repositories/baeldung/mesos-marathon-demo/tags
[{"layer": "", "name": "32"}, {"layer": "", "name": "33"}, {"layer": "", "name": "34"}]
As we can see, instead of a single array of tags, we have an array of objects. Each object includes the name of the tag and the layer ID of the image.
If needed, we can convert the response to an array. To do so, let’s pipe the output into the jq command and parse the JSON:
$ curl -s GET https://registry.hub.docker.com/v1/repositories/baeldung/mesos-marathon-demo/tags | jq -r '[.[].name]'
[
"32",
"33",
"34"
]
Let’s understand the jq command and expressions used here:
- The -r flag returns the output as raw text.
- The expression .[].name returns the name property from each object from the curl output.
- The square brackets [] around the expression indicate that we want to collect the output in an array.
Finally, the -s flag used with the curl command is required to suppress the progress bar output.
5. Conclusion
In this article, we’ve explored how to use the Docker Registry API to list images and tags in a remote registry.
We also looked at how to send paginated requests for images and tags and how to parse JSON responses.