1. Introduction

When working with Docker containers, it’s common to push and pull images to and from Docker Hub, the default registry service for Docker. Thus, ensuring that an image:tag combination doesn’t already exist in Docker Hub is important when managing images.

In this tutorial, we’ll explore methods for checking whether a particular image:tag combination already exists in Docker Hub. First, we’ll understand the importance of using tags. Next, we’ll learn how to check for the existence of the combination using Docker. Finally, we’ll study checking using Skopeo.

2. Tags in Docker Hub

Docker Hub uses tags to differentiate versions of a container image. They’re essential for managing our images, as they help us track and manage changes over time and facilitate version control and rollbacks when problems are found. In short, using tags in Docker Hub is essential to ensuring the reliability and consistency of the container images in our projects.

The identification of a container image typically comprises a descriptive name, followed by a colon (:), and a specific version, such as “latest” or “v1.0”. Also, we may employ other conventions.

It’s important to note that each combination of image name and tag must be unique in a given repository. For example, the Ubuntu repository may have the tag “latest” pointing to a specific image, while it may also have the tag “18.04” pointing to an earlier version of that image.

3. Checking Image:Tag on Docker Hub with Docker

The first method is in cases where we have access to a machine with Docker installed and configured on the system. This method is straightforward and requires no additional tools beyond Docker itself.

We’ll use the Docker manifest to do this. A manifest contains information about an image, such as its size, operating system, architecture, and more.

If we want to access a private registry, the first step is to log in to the Docker Hub:

$ docker login --username=<username> <registry>
Password: 
Login Succeeded

The Docker may return a warning message similar to the one below. Although it doesn’t prevent a successful login, we can remove it by following the docker login documentation.

WARNING! Your password will be stored unencrypted in /home/user/.docker/config.json.
Configure a credential helper to remove this warning.

So, to check if an image:tag exists, we run:

$ docker manifest inspect <image_name>:<image_tag>

Assuming that <image_name>:<image_tag> is replaced by ubuntu:latest, we get the result:

{
   "schemaVersion": 2,
   "mediaType": "application/vnd.oci.image.index.v1+json",
   "manifests": [
      {
         "mediaType": "application/vnd.oci.image.manifest.v1+json",
         "size": 424,
         "digest": "sha256:d21429c4635332e96a4baae3169e3f02ac8e24e6ae3d89a86002d49a1259a4f7",
         "platform": {
            "architecture": "amd64",
            "os": "linux"
         }
      },
      {
         "mediaType": "application/vnd.oci.image.manifest.v1+json",
         "size": 424,
         "digest": "sha256:d69717588093ca3aaa2b5721ba1b349c665417ed60509877a15538da12b73773",
         "platform": {
            "architecture": "arm",
            "os": "linux",
            "variant": "v7"
         }
      },
      {
         "mediaType": "application/vnd.oci.image.manifest.v1+json",
         "size": 424,
         "digest": "sha256:645f92f744c2414662a4fec7824969d037d193d8fdc420582d7a555da662b473",
         "platform": {
            "architecture": "arm64",
            "os": "linux",
            "variant": "v8"
         }
      },
      {
         "mediaType": "application/vnd.oci.image.manifest.v1+json",
         "size": 424,
         "digest": "sha256:b8212982a9407b19f42f0239dd3b8ab16a759a3ab89d6ed47aad40ac36337c16",
         "platform": {
            "architecture": "ppc64le",
            "os": "linux"
         }
      },
      {
         "mediaType": "application/vnd.oci.image.manifest.v1+json",
         "size": 424,
         "digest": "sha256:31e02f893eaf7729befc0e21920e63b968bffe76760943a6f56fa1c7f3abb055",
         "platform": {
            "architecture": "s390x",
            "os": "linux"
         }
      }
   ]
}

However, we can use an additional command to simplify the result returned:

$ docker manifest inspect <image_name>:<image_tag> > /dev/null ; echo $?

Thus, Docker will return 0 if the image and tag were found or 1 with a short message if not:

no such manifest: docker.io/library/ubuntu:30.1
1

An important note is that the Docker manifest is an experimental command, as specified in the official documentation. This means that it’s in the testing phase, and its functionality or design may change in the future.

4. Checking Image:Tag on Docker Hub with Skopeo

There are other methods of checking the combination. One of them is through Skopeo. Skopeo is a command-line utility for manipulating container images and repositories. It can handle OCI and Docker v2 images and manages different registries and repositories. Root privileges or a running daemon aren’t required to perform its operations. It can perform various operations such as copying, inspecting, deleting, and synchronizing images, as well as authenticating when necessary.

To do this, let’s install it using the command:

$ sudo apt install skopeo

Just like in Docker, we’re going to inspect a Docker Hub registry:

$ skopeo inspect docker://<registry>/<repository>:<image_tag>

We can, for example, check the tags registered in the Ubuntu repository:

$ skopeo inspect docker://docker.io/ubuntu
{
    "Name": "docker.io/library/ubuntu",
    "Digest": "sha256:3f85b7caad41a95462cf5b787d8a04604c8262cdcdf9a472b8c52ef83375fe15",
    "RepoTags": [
            ...,
        "noble",
        "noble-20231126.1",
        "noble-20231214",
        "noble-20231221",
        "noble-20240114",
        "noble-20240127.1",
        "noble-20240212",
        "noble-20240225",
        "noble-20240407.1",
        "noble-20240423",
        "noble-20240429",
        ...,
    ],
    "Created": "2024-04-29T16:38:03.122210017Z",
    "DockerVersion": "24.0.5",
    "Labels": {
        "org.opencontainers.image.ref.name": "ubuntu",
        "org.opencontainers.image.version": "24.04"
    },
    "Architecture": "amd64",
    "Os": "linux",
    "Layers": [
        "sha256:49b384cc7b4aa0dfd16ff7817ad0ea04f1d0a8072e62114efcd99119f8ceb9ed"
    ],
    "Env": [
        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
    ]
}

The RepoTags field showed about 600 tags in total. For simplicity, the result shown above only includes images from the latest released version, called Noble Numbat.

If Skopeo doesn’t find the requested image, it returns an error similar to the following:

FATA[0001] Error parsing image name "docker://docker.io/image": reading manifest latest in docker.io/library/image: errors

As the result returned by Skopeo is extensive, we can add the same command we did earlier when using Docker:

$ skopeo inspect docker://<registry>/<repository>:<image-tag> > /dev/null ; echo $?

Likewise, the system will return 0 on success or 1 on failure.

5. Conclusion

In this tutorial, we explored the relevance of using tags. We explored two methods for checking whether an image:tag combination already exists in Docker Hub using Docker itself and Skopeo.

In summary, when Docker is installed, we can use the docker manifest inspect command to search for combinations on Docker Hub. Otherwise, Skopeo is a suitable alternative for more detailed information about the image.