Three Ways to Check a Docker Image Exists In Registry
There’s sometimes need to check if a Docker image already exists in a registry and repository. There might be numerous tools for that, let’s have a look at three of them today.
What I should probably say at the beginning is that I’m talking about a remote registry, not about a local storage. And I don’t want to pull an image at the same time, I just want to check whether or not the image lives in the registry.
Docker
Docker is probably the first tool that comes to mind. But it’s not really what docker
has been built for.
There’s docker manifest inspect
command that can be used for this. But docker manifest
is an experimental command (for a couple of years now), so even though Docker says:
Starting with Docker 20.10, experimental CLI features are enabled by default, and require no configuration to enable them.
it’s still probably better not to use experimental commands for important things (like CI pipelines).
Anyway, if you do want to use this command, this is how you do it:
$ docker manifest inspect <registry>/<repository>[:tag]
The command returns 0 if the image exists in the registry and repository, and 1 if it does not.
docker
is also available in GitHub runners (I really ever tried ubuntu-latest
), so no need to install any other software.
Skopeo
Skopeo is another tool for this task. It can be done with the following command:
skopeo inspect docker://<registry>/<repository>[:image-tag]
Since version 1.5.1, there’s also — no-tags
option that does not pull all image tags with this command, which can significantly reduce an execution time:
timeit () {
command time -f "%e" "$@"
}
and:
$ timeit skopeo inspect --no-tags docker://docker.io/debian
takes about 3 seconds, whereas:
$ timeit skopeo inspect docker://docker.io/debian
takes about 5 seconds.
The catch here is that Ubuntu 22.04 as a GitHub runner has only skopeo 1.4.1 (as of September 2022). That means no --no-tags
option and a lot of wasted time.
Aws
Last command I’ve used is aws ecr describe-images
. It’s again available in GitHub runners (at least in Ubuntu 22.04).
To check whether or not a docker image exists in a registry and repository, I can use:
$ aws ecr describe-images --registry-id <account-id> --repository-name <repository-name> --image-ids imageTag=<image-tag>
A bit longer, but works fast and is not experimental. The command returns 0 if the image is found, non zero status code if not.
What might be a bit confusing is what some of the language means in some of these commands. At least for somebody new, it might be confusing to know what registry, repository, registry-id, etc. mean. Let’s spend a moment on that.
docker
and skopeo
can be used with the following format:
<registry-uri>/<repository>[:tag]
Skopeo also needs docker://
in front of the registry URI.
If I use the official Docker registry, it might be something like this:
docker.io/debian:wheezy-slim
docker.io
is a registry, debian
is a repository, and wheezy-slim
is an image tag.
How about with private registries? For example something like Amazon ECR private registries. In this case, a registry URI will be in such a format:
aws_account_id.dkr.ecr.region.amazonaws.com
but aws ecr describe-images
takes a registry id, so where do I find it? Well, it turnes out that --registry-id
is:
The Amazon Web Services account ID associated with the registry that contains the repository in which to describe images. If you do not specify a registry, the default registry is assumed.
So aws_account_id
from the registry URI will do here.
Let’s then say we’re building an API. It’ll become a Docker image within our private Amazon ECR registry. We might call a repository for our API just api
. We also might tag each new docker image with a version something like 0.1.1254
, 0.1.1255
, etc.
Then to check if an image is in this registry and repository, I might use any of these three commands:
$ docker manifest inspect aws_account_id.dkr.ecr.region.amazonaws.com/api:0.1.1254
$ skopeo inspect docker://aws_account_id.dkr.ecr.region.amazonaws.com/api:0.1.1254
$ aws ecr describe-images --registry-id <aws_account_id> --repository-name api --image-ids imageTag=0.1.1254
Obviously I have to be logged in when it’s a private registry. There might be more ways to do so, for example aws-actions/amazon-ecr-login
GitHub action from Amazon.
So here you go, three ways to check for an image in a registry without pulling the image. There might be more nuances to it, but as an introduction, this should steer you to the right direction.