Skip to content

Instantly share code, notes, and snippets.

@robv8r
Last active November 3, 2023 14:11
Show Gist options
  • Save robv8r/fa66f5e0fdf001f425fe9facf2db6d49 to your computer and use it in GitHub Desktop.
Save robv8r/fa66f5e0fdf001f425fe9facf2db6d49 to your computer and use it in GitHub Desktop.
List Docker Image Tags using bash
#!/usr/bin/env bash
# Gets all tags for a given docker image.
# Examples:
# retrieve all tags for a single library
# docker-tags "library/redis" | jq --raw-output '.[]'
# retrieve all tags for multiple libraries
# docker-tags "library/mongo" "library/redis" "microsoft/nanoserver" "microsoft/dotnet" | jq --raw-output '.[]'
# retrieve first 10 tags for multiple libraries
# docker-tags "library/mongo" "library/redis" "microsoft/nanoserver" "microsoft/dotnet" | jq --raw-output '.[][0:9]'
docker-tags() {
arr=("$@")
for item in "${arr[@]}";
do
tokenUri="https://auth.docker.io/token"
data=("service=registry.docker.io" "scope=repository:$item:pull")
token="$(curl --silent --get --data-urlencode ${data[0]} --data-urlencode ${data[1]} $tokenUri | jq --raw-output '.token')"
listUri="https://registry-1.docker.io/v2/$item/tags/list"
authz="Authorization: Bearer $token"
result="$(curl --silent --get -H "Accept: application/json" -H "Authorization: Bearer $token" $listUri | jq --raw-output '.')"
echo $result
done
}
@DKroot
Copy link

DKroot commented Nov 6, 2018

This breaks down on docker-tags ubuntu:

{ "errors": [ { "code": "UNAUTHORIZED", "message": "authentication required", "detail": [ { "Type": "repository", "Class": "", "Name": "ubuntu", "Action": "pull" } ] } ] }

@hlzhang
Copy link

hlzhang commented Nov 9, 2018

+1 UNAUTHORIZED.

{"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":[{"Type":"repository","Class":"","Name":"cloudready/spring-cloud-config-server","Action":"pull"}]}]}

@robv8r
Copy link
Author

robv8r commented Nov 20, 2018

@DKroot - By itself, "ubuntu" isn't a valid package name. I recommend looking for "library/ubuntu" instead.


Edit (added example)

The following example lists all tags for "ubuntu":

docker-tags "library/ubuntu" | jq --raw-output '.["tags"]'

The result (on my computer) is:

[
  "10.04",
  "12.04.5",
  "12.04",
  "12.10",
  "13.04",
  "13.10",
  "14.04.1",
  "14.04.2",
  "14.04.3",
  "14.04.4",
  "14.04.5",
  "14.04",
  "14.10",
  "15.04",
  "15.10",
  "16.04",
  "16.10",
  "17.04",
  "17.10",
  "18.04",
  ...etc
]

@robv8r
Copy link
Author

robv8r commented Nov 20, 2018

@chshawkn

+1 UNAUTHORIZED.

{"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":[{"Type":"repository","Class":"","Name":"cloudready/spring-cloud-config-server","Action":"pull"}]}]}

This is working for me. Can you give me more information regarding your setup?

The command I'm executing is:

docker-tags "cloudready/spring-cloud-config-server" | jq --raw-output '.["tags"]'

The output is

[
  "0.0.2",
  "0.0.4",
  "0.0.5-SNAPSHOT",
  "0.0.5",
  "0.0.6-SNAPSHOT",
  "0.1.0-SNAPSHOT",
  "1.0.0",
  "1.0.1-SNAPSHOT",
  "1.0.1.U1",
  "1.0.1.U2",
  "1.0.1",
  "1.0.2-SNAPSHOT",
  "2.0.1-SNAPSHOT",
  "2.0.1-springboot2-SNAPSHOT"
]

@matrey
Copy link

matrey commented Jun 25, 2021

Several scopes can be requested at the same time, you don't need to get a new token for each image:

token_uri="https://auth.docker.io/token"
list_uri="https://registry-1.docker.io/v2/###IMAGE###/tags/list"

images=( "library/python" "library/ubuntu" )

scope=''
for image in "${images[@]}"; do
    scope+="scope=repository:${image}:pull&"
done

token=$( curl -Ss "${token_uri}?service=registry.docker.io&${scope}" | jq -r .token )

for image in "${images[@]}"; do
    this_uri=$( echo -n "${list_uri}" | sed -e "s^###IMAGE###^${image}^" )
    curl -Ss -H "Accept: application/json" -H "Authorization: Bearer $token" "${this_uri}" | jq .
done

@gangefors
Copy link

gangefors commented Sep 17, 2021

Based on @matrey's comment, the updated script would look like this.

#!/usr/bin/env bash

# Gets all tags for a given docker image.

# Dependencies: curl, jq

# Examples:

# retrieve all tags for a single library
# docker-tags "library/redis"

# retrieve all tags for multiple libraries
# docker-tags "library/mongo" "library/redis"

token_uri="https://auth.docker.io/token"
list_uri="https://registry-1.docker.io/v2/###IMAGE###/tags/list"

images=($@)

scope=''
for image in "${images[@]}"; do
    scope+="scope=repository:${image}:pull&"
done

token=$( curl -Ss "${token_uri}?service=registry.docker.io&${scope}" | jq -r .token )

for image in "${images[@]}"; do
    this_uri=$( echo -n "${list_uri}" | sed -e "s^###IMAGE###^${image}^" )
    curl -Ss -H "Accept: application/json" -H "Authorization: Bearer $token" "${this_uri}" | jq .
done

@jcwatson11
Copy link

How can I use this to access a private repo? I keep getting the "UNAUTHORIZED" "authentication required" response, and I don't know how to provide my credentials.

@robv8r
Copy link
Author

robv8r commented Jun 14, 2022

@jcwatson11: It depends on the authentication mechanism of your private repository. What type of private repository are your working with? Specifically, is it registry:2, ghcr.io, or a hosted provider?

@tripleee
Copy link

tripleee commented Jul 3, 2023

arr=("$@")
for item in "${arr[@]}";

This is just a clumsy and memory-squandering way to say for item in "$@";

images=($@)
for image in "${images[@]}"; do

This adds a quoting error (you want "$@", always, not a bare $@).

@dkebler
Copy link

dkebler commented Oct 4, 2023

Thx for this script. I used a bit of jq/sort/sed to get the version number of the "latest" tag like so. Given that an image can have many tags going way back one probably needs to know apriori which major version is the "latest" and supply that.

docker_latest_image() {
    image=$1
    major=${2:-1}
    tokenUri="https://auth.docker.io/token"
    data=("service=registry.docker.io" "scope=repository:$image:pull")
    token="$(curl --silent --get --data-urlencode ${data[0]} --data-urlencode ${data[1]} $tokenUri | jq --raw-output '.token')"
    listUri="https://registry-1.docker.io/v2/$image/tags/list"
    curl --silent --get -H "Accept: application/json" -H "Authorization: Bearer $token" $listUri \
    | jq --raw-output ".tags[] | select(. | startswith(\"$major.\"))" | sort -V | sed -n \$p
   }
docker_latest_image  library/alpine 3
3.18.4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment