0

I'm using an image that sometimes has a rolling version change (namespace/repo:...-1 -> -2) and they also delete the old version. I am trying to pull their image but a regex doesn't work. I tried docker pull namespace/repo:....-* and so on. Is there any way to pull a docker image using a regex/wildcard or fetch the latest rolling version?

EliasV
  • 8
  • 6
  • Often registries have a web interface that you might be able to access. So try the base URL in the browser and you can maybe browse through the registry (e.g. harbor) and find the image with its tags – h0ch5tr4355 Aug 21 '23 at 11:21
  • @h0ch5tr4355 I know which tags exist, but I still need to use regex/wildcard so I won't have to update the rolling version number each time they update theirs – EliasV Aug 21 '23 at 11:25
  • There is no support for pulling images based on a wildcard expression. You could probably script something up using the `skopeo list-tags` command ([skopeo](https://github.com/containers/skopeo)) or [interact with the docker hub API directly](https://stackoverflow.com/a/39454426/147356). – larsks Aug 21 '23 at 12:21

2 Answers2

0

This is not a capability of docker pull or any of the other container runtimes that I'm aware of. The typical process used by the image publisher is to publish multiple tags, e.g. namespace/repo:v1.2.3-4, namespace/repo:v1.2.3, namespace/repo:v1.2, and namespace/repo:v1 that all point to the same underlying manifest. Then when the -5 is released, the less specific tags are also updated and users pick what level of granularity they require in the tag name they use.

The other option is to used a tool that can lists tags in a repository. That API is part of the OCI distribution-spec implemented by most container registries. Various client side tools expose this API, in particular Google's crane, RedHat's skopeo, and my own regclient each implement the tag listing query. From there, you script that output to grep, e.g.:

$ regctl tag ls golang | egrep '1\.21\..*-alpine$'
1.21.0-alpine

You'd then want to do a semver sort on output like the above, or a numeric sort on a single part of the version.

BMitch
  • 231,797
  • 42
  • 475
  • 450
0

Expanding on my comment, interacting with the Docker Hub API directly you could use something like this:

#!/bin/bash

[[ $1 =~ (([^/]*)/)?([^:]*)(:(.*))? ]]

repo=${BASH_REMATCH[2]}
image=${BASH_REMATCH[3]}
tag=${BASH_REMATCH[5]}

found_tag=$(
    curl -sSf \
    "https://hub.docker.com/v2/namespaces/${repo:-library}/repositories/${image}/tags?page_size=100" |
    jq -r '.results|sort_by(.last_updated)[]|.name' |
    tee sorted |
    grep "${tag:-.}" |
    tail -1
)

if [[ -z $found_tag ]]; then
    echo "ERROR: no matching tags" >&2
    exit 1
fi

echo "${repo:+$repo/}$image:$found_tag"

This will return the most recent (by date last updated) tag matching a regular expression. Assuming we have named this script get-latest-matching, we would see:

$ get-latest-matching golang
golang:latest
$ get-latest-matching golang:1.21
golang:1.21.0-bullseye
$ get-latest-matching golang:1.21\$
golang:1.21
$ get-latest-matching golang:1.21.\*alpine
golang:1.21.0-alpine3.18
$ get-latest-matching golang:1.21.\*alpine\$
golang:1.21.0-alpine

It works just as well with non-library images:

$ get-latest-matching netboxcommunity/netbox
netboxcommunity/netbox:snapshot-2.6.1
$ bash get-latest-matching netboxcommunity/netbox:v3
netboxcommunity/netbox:v3.5-2.6.1
larsks
  • 277,717
  • 41
  • 399
  • 399