How can I find a Docker image with a specific tag in Docker registry on the Docker command line?
Asked Answered
T

11

67

I try to locate one specific tag for a Docker image. How can I do it on the command line? I want to avoid downloading all the images and then removing the unneeded ones.

In the official Ubuntu release, https://registry.hub.docker.com/_/ubuntu/, there are several tags (release for it), while when I search it on the command line,

user@ubuntu:~$ docker search ubuntu | grep ^ubuntu
ubuntu              Official Ubuntu base image                          354
ubuntu-upstart      Upstart is an event-based replacement for ...   7
ubuntufan/ping                                                0
ubuntu-debootstrap                                                   0

Also in the help of command line search https://docs.docker.com/engine/reference/commandline/search/, no clue how it can work?

Is it possible in the docker search command?

If I use a raw command to search via the Docker registry API, then the information can be fetched:

   $ curl https://registry.hub.docker.com//v1/repositories/ubuntu/tags | python -mjson.tool
   [
    {
        "layer": "ef83896b",
        "name": "latest"
    },
    .....
    {
        "layer": "463ff6be",
        "name": "raring"
    },
    {
        "layer": "195eb90b",
        "name": "saucy"
    },
    {
        "layer": "ef83896b",
        "name": "trusty"
    }
]
Tychonn answered 30/6, 2014 at 0:37 Comment(0)
L
12

As far as I know, the CLI does not allow searching/listing tags in a repository.

But if you know which tag you want, you can pull that explicitly by adding a colon and the image name: docker pull ubuntu:saucy

Loaiasis answered 30/6, 2014 at 8:49 Comment(3)
do you know any issues in github linked to this ?Tychonn
@LarryCai No, and I could not find any in a quick search.Pone
I added this to a proposal for the new Registry API: Proposal: JSON Registry API V2.1 · Issue #9015 · docker/dockerPortiere
I
43

When using CoreOS, jq is available to parse JSON data.

So like you were doing before, looking at library/centos:

$ curl -s -S 'https://registry.hub.docker.com/v2/repositories/library/centos/tags/' | jq '."results"[]["name"]' |sort
"6"
"6.7"
"centos5"
"centos5.11"
"centos6"
"centos6.6"
"centos6.7"
"centos7.0.1406"
"centos7.1.1503"
"latest"

The cleaner v2 API is available now, and that's what I'm using in the example. I will build a simple script docker_remote_tags:

#!/usr/bin/bash
curl -s -S "https://registry.hub.docker.com/v2/repositories/library/$@/tags/" | jq '."results"[]["name"]' |sort

Enables:

$ ./docker_remote_tags library/centos
"6"
"6.7"
"centos5"
"centos5.11"
"centos6"
"centos6.6"
"centos6.7"
"centos7.0.1406"
"centos7.1.1503"
"latest"

Reference:

jq: https://stedolan.github.io/jq/ | apt-get install jq

Indus answered 17/9, 2015 at 3:27 Comment(4)
My jq version (jq-1.4-1-e73951f in Fedora 22) requires the "results" without quotes. I.e. jq '.results[]["name"]'Agribusiness
I merged above example and that example. As a result following docker image was created.Parsee
This will only get your the latest 10 tags -- it will not show you anything older that doesn't fit into the first 10 items.Pecksniffian
@Agribusiness you can get the result without quote using the -r flag of jqDartmouth
P
19

I didn't like any of the solutions above because A) they required external libraries that I didn't have and didn't want to install. B) I didn't get all the pages.

The Docker API limits you to 100 items per request. This will loop over each "next" item and get them all (for Python it's seven pages; other may be more or less... It depends)

If you really want to spam yourself, remove | cut -d '-' -f 1 from the last line, and you will see absolutely everything.

url=https://registry.hub.docker.com/v2/repositories/library/redis/tags/?page_size=100 `# Initial url` ; \
( \
  while [ ! -z $url ]; do `# Keep looping until the variable url is empty` \
    >&2 echo -n "." `# Every iteration of the loop prints out a single dot to show progress as it got through all the pages (this is inline dot)` ; \
    content=$(curl -s $url | python -c 'import sys, json; data = json.load(sys.stdin); print(data.get("next", "") or ""); print("\n".join([x["name"] for x in data["results"]]))') `# Curl the URL and pipe the output to Python. Python will parse the JSON and print the very first line as the next URL (it will leave it blank if there are no more pages) then continue to loop over the results extracting only the name; all will be stored in a variable called content` ; \
    url=$(echo "$content" | head -n 1) `# Let's get the first line of content which contains the next URL for the loop to continue` ; \
    echo "$content" | tail -n +2 `# Print the content without the first line (yes +2 is counter intuitive)` ; \
  done; \
  >&2 echo `# Finally break the line of dots` ; \
) | cut -d '-' -f 1 | sort --version-sort | uniq;

Sample output:

$ url=https://registry.hub.docker.com/v2/repositories/library/redis/tags/?page_size=100 `#initial url` ; \
> ( \
>   while [ ! -z $url ]; do `#Keep looping until the variable url is empty` \
>     >&2 echo -n "." `#Every iteration of the loop prints out a single dot to show progress as it got through all the pages (this is inline dot)` ; \
>     content=$(curl -s $url | python -c 'import sys, json; data = json.load(sys.stdin); print(data.get("next", "") or ""); print("\n".join([x["name"] for x in data["results"]]))') `# Curl the URL and pipe the JSON to Python. Python will parse the JSON and print the very first line as the next URL (it will leave it blank if there are no more pages) then continue to loop over the results extracting only the name; all will be store in a variable called content` ; \
>     url=$(echo "$content" | head -n 1) `#Let's get the first line of content which contains the next URL for the loop to continue` ; \
>     echo "$content" | tail -n +2 `#Print the content with out the first line (yes +2 is counter intuitive)` ; \
>   done; \
>   >&2 echo `#Finally break the line of dots` ; \
> ) | cut -d '-' -f 1 | sort --version-sort | uniq;
...
2
2.6
2.6.17
2.8
2.8.6
2.8.7
2.8.8
2.8.9
2.8.10
2.8.11
2.8.12
2.8.13
2.8.14
2.8.15
2.8.16
2.8.17
2.8.18
2.8.19
2.8.20
2.8.21
2.8.22
2.8.23
3
3.0
3.0.0
3.0.1
3.0.2
3.0.3
3.0.4
3.0.5
3.0.6
3.0.7
3.0.504
3.2
3.2.0
3.2.1
3.2.2
3.2.3
3.2.4
3.2.5
3.2.6
3.2.7
3.2.8
3.2.9
3.2.10
3.2.11
3.2.100
4
4.0
4.0.0
4.0.1
4.0.2
4.0.4
4.0.5
4.0.6
4.0.7
4.0.8
32bit
alpine
latest
nanoserver
windowsservercore

If you want the bash_profile version:

function docker-tags () {
  name=$1
  # Initial URL
  url=https://registry.hub.docker.com/v2/repositories/library/$name/tags/?page_size=100
  (
    # Keep looping until the variable URL is empty
    while [ ! -z $url ]; do
      # Every iteration of the loop prints out a single dot to show progress as it got through all the pages (this is inline dot)
      >&2 echo -n "."
      # Curl the URL and pipe the output to Python. Python will parse the JSON and print the very first line as the next URL (it will leave it blank if there are no more pages)
      # then continue to loop over the results extracting only the name; all will be stored in a variable called content
      content=$(curl -s $url | python -c 'import sys, json; data = json.load(sys.stdin); print(data.get("next", "") or ""); print("\n".join([x["name"] for x in data["results"]]))')
      # Let's get the first line of content which contains the next URL for the loop to continue
      url=$(echo "$content" | head -n 1)
      # Print the content without the first line (yes +2 is counter intuitive)
      echo "$content" | tail -n +2
    done;
    # Finally break the line of dots
    >&2 echo
  ) | cut -d '-' -f 1 | sort --version-sort | uniq;
}

And simply call it: docker-tags redis

Sample output:

$ docker-tags redis
...
2
2.6
2.6.17
2.8

--trunc----

32bit
alpine
latest
nanoserver
windowsservercore
Pecksniffian answered 22/2, 2018 at 15:36 Comment(2)
note this requires python. ... "(A) they required external libraries"Indus
@Indus I haven't seen a *nix box that doesn't have python installed in the last 10 years.Pecksniffian
L
12

As far as I know, the CLI does not allow searching/listing tags in a repository.

But if you know which tag you want, you can pull that explicitly by adding a colon and the image name: docker pull ubuntu:saucy

Loaiasis answered 30/6, 2014 at 8:49 Comment(3)
do you know any issues in github linked to this ?Tychonn
@LarryCai No, and I could not find any in a quick search.Pone
I added this to a proposal for the new Registry API: Proposal: JSON Registry API V2.1 · Issue #9015 · docker/dockerPortiere
F
10

This script (docker-show-repo-tags.sh) should work for any Docker enabled host that has curl, sed, grep, and sort. This was updated to reflect the fact the repository tag URLs changed.

This version correctly parses the "name": field without a JSON parser.

#!/bin/sh
# 2022-07-20
# Simple script that will display Docker repository tags
# using basic tools: curl, awk, sed, grep, and sort.
# Usage:
#   $ docker-show-repo-tags.sh ubuntu centos
#   $ docker-show-repo-tags.sh centos | cat -n
for Repo in "$@" ; do
    URL="https://registry.hub.docker.com/v2/repositories/library/$Repo/tags/"
    curl -sS "$URL" | \
        /usr/bin/sed -Ee 's/("name":)"([^"]*)"/\n\1\2\n/g' | \
        grep '"name":' | \
        awk -F: '{printf("'$Repo':%s\n",$2)}'
done

This older version no longer works. Many thanks to @d9k for pointing this out!

#!/bin/sh
# WARNING: This no long works!
# Simple script that will display Docker repository tags
# using basic tools: curl, sed, grep, and sort.
#
# Usage:
#   $ docker-show-repo-tags.sh ubuntu centos
for Repo in $* ; do
    curl -sS "https://hub.docker.com/r/library/$Repo/tags/" | \
        sed -e $'s/"tags":/\\\n"tags":/g' -e $'s/\]/\\\n\]/g' | \
        grep '^"tags"' | \
        grep '"library"' | \
        sed -e $'s/,/,\\\n/g' -e 's/,//g' -e 's/"//g' | \
        grep -v 'library:' | \
        sort -fu | \
        sed -e "s/^/${Repo}:/"
done

This older version no longer works. Many thanks to @viky for pointing this out!

#!/bin/sh
# WARNING: This no long works!
# Simple script that will display Docker repository tags.
#
# Usage:
#   $ docker-show-repo-tags.sh ubuntu centos
for Repo in $* ; do
  curl -s -S "https://registry.hub.docker.com/v2/repositories/library/$Repo/tags/" | \
    sed -e $'s/,/,\\\n/g' -e $'s/\[/\\\[\n/g' | \
    grep '"name"' | \
    awk -F\" '{print $4;}' | \
    sort -fu | \
    sed -e "s/^/${Repo}:/"
done

This is the output for a simple example:

$ docker-show-repo-tags.sh centos | cat -n
     1    centos:5
     2    centos:5.11
     3    centos:6
     4    centos:6.10
     5    centos:6.6
     6    centos:6.7
     7    centos:6.8
     8    centos:6.9
     9    centos:7.0.1406
    10    centos:7.1.1503
    11    centos:7.2.1511
    12    centos:7.3.1611
    13    centos:7.4.1708
    14    centos:7.5.1804
    15    centos:centos5
    16    centos:centos5.11
    17    centos:centos6
    18    centos:centos6.10
    19    centos:centos6.6
    20    centos:centos6.7
    21    centos:centos6.8
    22    centos:centos6.9
    23    centos:centos7
    24    centos:centos7.0.1406
    25    centos:centos7.1.1503
    26    centos:centos7.2.1511
    27    centos:centos7.3.1611
    28    centos:centos7.4.1708
    29    centos:centos7.5.1804
    30    centos:latest
Ferree answered 2/12, 2015 at 23:13 Comment(7)
I like prefer to use jshon: curl -s -S "https://registry.hub.docker.com/v2/repositories/library/centos/tags/" | jshon -e results -a -e name -u But yours is better for using built in toolsLux
your command shows only ➜ ~ docker-show-repo-tags.sh ubuntu ubuntu:next ➜ ~ docker-show-repo-tags.sh nginx nginx:nextPepe
Thank you @viky for pointing out that the example did not work. I have updated it.Ferree
doesn't work: no tags output :(Patsy
What happens when you run the curl command by itself? Something like curl -s -S "https://registry.hub.docker.com/v2/repositories/library/ubuntu/tags/" for ubuntu. It looks like the format may have changed.Ferree
It looks like the format changed, here is an example that should work that using jq to parse the JSON: esentire % export XX="centos" ; curl -s -S "https://registry.hub.docker.com/v2/repositories/library/$XX/tags/" | jq -M '.results[]|.name' | tr -d '"' | xargs -I{} printf "%s:%s\n" "$XX" "{}" ; unset XX. I will update the script above.Ferree
@d9k, i have updated the script to work correctly based on your feedback. Thank you for pointing out the problem.Ferree
P
6

I wrote a command line tool to simplify searching Docker Hub repository tags, available in my PyTools GitHub repository. It's simple to use with various command line switches, but most basically:

./dockerhub_show_tags.py repo1 repo2

It's even available as a Docker image and can take multiple repositories:

docker run harisekhon/pytools dockerhub_show_tags.py centos ubuntu

DockerHub

repo: centos
tags: 5.11
      6.6
      6.7
      7.0.1406
      7.1.1503
      centos5.11
      centos6.6
      centos6.7
      centos7.0.1406
      centos7.1.1503

repo: ubuntu
tags: latest
      14.04
      15.10
      16.04
      trusty
      trusty-20160503.1
      wily
      wily-20160503
      xenial
      xenial-20160503

If you want to embed it in scripts, use -q / --quiet to get just the tags, like normal Docker commands:

./dockerhub_show_tags.py centos -q
5.11
6.6
6.7
7.0.1406
7.1.1503
centos5.11
centos6.6
centos6.7
centos7.0.1406
centos7.1.1503
Parturient answered 25/5, 2016 at 10:22 Comment(1)
Docker image worked like a charm for me. It seems very hard to get at the full list of images any other way through the Docker hub site, so this script was perfect.Rissole
F
3

The v2 API seems to use some kind of pagination, so that it does not return all the available tags. This is clearly visible in projects such as python (or library/python). Even after quickly reading the documentation, I could not manage to work with the API correctly (maybe it is the wrong documentation).

Then I rewrote the script using the v1 API, and it is still using jq:

#!/bin/bash

repo="$1"

if [[ "${repo}" != */* ]]; then
    repo="library/${repo}"
fi

url="https://registry.hub.docker.com/v1/repositories/${repo}/tags"
curl -s -S "${url}" | jq '.[]["name"]' | sed 's/^"\(.*\)"$/\1/' | sort

The full script is available at: https://github.com/denilsonsa/small_scripts/blob/master/docker_remote_tags.sh

I've also written an improved version (in Python) that aggregates tags that point to the same version: https://github.com/denilsonsa/small_scripts/blob/master/docker_remote_tags.py

Fishbolt answered 19/3, 2016 at 1:17 Comment(0)
G
2

Add this function to your .zshrc file or run the command manually:

#usage list-dh-tags <repo>
#example: list-dh-tags node
function list-dh-tags(){
    wget -q https://registry.hub.docker.com/v1/repositories/$1/tags -O -  | sed -e 's/[][]//g' -e 's/"//g' -e 's/ //g' | tr '}' '\n'  | awk -F: '{print $3}'
}

Thanks to this -> How can I list all tags for a Docker image on a remote registry?

Griskin answered 19/7, 2018 at 11:5 Comment(0)
I
2

For anyone stumbling across this in modern times, you can use Skopeo to retrieve an image's tags from the Docker registry:

$ skopeo list-tags docker://jenkins/jenkins \
| jq -r '.Tags[] | select(. | contains("lts-alpine"))' \
| sort --version-sort --reverse

lts-alpine
2.277.3-lts-alpine
2.277.2-lts-alpine
2.277.1-lts-alpine
2.263.4-lts-alpine
2.263.3-lts-alpine
2.263.2-lts-alpine
2.263.1-lts-alpine
2.249.3-lts-alpine
2.249.2-lts-alpine
2.249.1-lts-alpine
2.235.5-lts-alpine
2.235.4-lts-alpine
2.235.3-lts-alpine
2.235.2-lts-alpine
2.235.1-lts-alpine
2.222.4-lts-alpine
Itu answered 21/4, 2021 at 21:17 Comment(0)
D
0

Reimplementation of the previous post, using Python over sed/AWK:

for Repo in $* ; do
    tags=$(curl -s -S "https://registry.hub.docker.com/v2/repositories/library/$Repo/tags/")
    python - <<EOF

import json

tags = [t['name'] for t in json.loads('''$tags''')['results']]
tags.sort()
for tag in tags:
    print "{}:{}".format('$Repo', tag)
EOF
done
Day answered 19/2, 2016 at 12:25 Comment(2)
Isn't it customary to have import statements at the top?Fancyfree
The import is at the top… of the python script. Read carefuly,, Chris used here-doc syntax. So he first use bash (withcurl), then python. I don't understand why he didn't do all of it in python.Aerodrome
L
0

For a script that works with OAuth bearer tokens on Docker Hub, try this:

Listing the tags of a Docker image on a Docker hub through the HTTP API

Legality answered 9/7, 2016 at 2:30 Comment(0)
T
0

You can use Visual Studio Code to provide autocomplete for available Docker images and tags. However, this requires that you type the first letter of a tag in order to see autocomplete suggestions.

For example, when writing FROM ubuntu it offers autocomplete suggestions like ubuntu, ubuntu-debootstrap and ubuntu-upstart. When writing FROM ubuntu:a it offers autocomplete suggestions, like ubuntu:artful and ubuntu:artful-20170511.1

Trinidad answered 28/3, 2019 at 10:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.