Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I would like to list the tags of a Docker image official Docker hub through its HTTP interface, but I am a bit confused. As there seems to two versions of them:

  • https://docs.docker.com/v1.6/reference/api/registry_api/
  • https://docs.docker.com/v1.6/registry/spec/api/

I managed to get them through sending a GET request to this endpoint: https://index.docker.io/v1/repositories/{my-namespace}/{my-repository}/tags along with basic authentication credentials.

I am not sure if there is a correct one among them, but which should I be using?

like image 712
tugberk Avatar asked Feb 12 '16 11:02

tugberk


2 Answers

I'm arriving a little late, I searched this question as list all tags for the same image (understand digest), unfortunately most of the answers are only about displaying all available tags for any image digest that was pushed.

Case in hand, for open jdk the same image digest is usually tagged multiple times :

  {
    "sha256:518f6c2137b7463272cb1f52488e914b913b92bfe0783acb821c216987959971": [
      "11",
      "11-buster",
      "11-jdk",
      "11-jdk-buster",
      "11.0",
      "11.0-buster",
      "11.0-jdk",
      "11.0-jdk-buster",
      "11.0.8",
      "11.0.8-buster",
      "11.0.8-jdk",
      "11.0.8-jdk-buster"
    ]
  },

I wasn't able to find the relevant API v2, it seems the api exposes tags, but there's no details and otherwise you need to list each blob manifest to get matching digest via the response header Docker-Content-Digest. I Unless I missed something this unusable for my use case when there is a lot of tags, so I just used the regular dockerhub API to get all tags and teir details and group these tags by the image digest.

(
  url="https://registry.hub.docker.com/v2/repositories/library/openjdk/tags/?page_size=100" ;
  while [ -n "$url" ]; do
    >&2 echo -n ".";
    content="$(curl -s "$url")";
    url=$(jq -r '.next // empty' <<< "${content}");
    echo "$content";
  done;
  >&2 echo;
) | jq -s '[.[].results[]]' \
  | jq 'map({tag: .name, digest: .images[].digest}) | unique | group_by(.digest) | map(select(.[].digest) | {(.[0].digest): [.[].tag]})' \
  > openjdk-tags.json

I've published this as a script in this gist, any comment or suggestion would be appreciated.

like image 101
Brice Avatar answered Sep 20 '22 12:09

Brice


Update for Docker V2 API

The Docker V2 API requires an OAuth bearer token with the appropriate claims. In my opinion, the official documentation is rather vague on the topic. So that others don't go through the same pain I did, I offer the below docker-tags function.

The most recent version of docker-tags can be found in my GitHubGist : "List Docker Image Tags using bash".

The docker-tags function has a dependency on jq. If you're playing with JSON, you likely already have it.

#!/usr/bin/env bash
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
}

Example

docker-tags "microsoft/nanoserver" "microsoft/dotnet" "library/mongo" "library/redis"

Admittedly, docker-tags makes several assumptions. Specifically, the OAuth request parameters are mostly hard coded. A more ambitious implementation would make an unauthenticated request to the registry and derive the OAuth parameters from the unauthenticated response.

like image 43
RobV8R Avatar answered Sep 21 '22 12:09

RobV8R