Search code examples
dockerdocker-registrydocker-api

Retrieve Docker image tags from a 3rd party repo


For Docker images that come straight from Docker Hub, I can retrieve the current list of tags for an image by hitting their repository API. For example, https://registry.hub.docker.com/v1/repositories/python/tags will give me a list of tags that can be used with docker pull python:<tag>.

For Elastic Search, I'm using their official repository and can pull an image using something like docker pull docker.elastic.co/elasticsearch/elasticsearch:6.4.0

However, I can't figure out how to pull a list of tags from that repository. I've tried

https://docker.elastic.co/elasticsearch/elasticsearch/tags
https://docker.elastic.co/v1/repositories/elasticsearch
https://docker.elastic.co/v2/repositories/elasticsearch/elasticsearch/_manifests/tags

..and several other variations. What URL/API endpoints is the docker command line tool translating that repository/image name into on the backend request?


Solution

  • It turns out that docker.elastic.co is running a V2 docker registry, so it requires V2 API commands and token authentication. Trying to initially get the tags results in a 401 with information on how to get the token:

    http https://docker.elastic.co/v2/elasticsearch/elasticsearch/tags/list                                                                                                                       (566ms)  
    HTTP/1.1 401 Unauthorized
    Connection: keep-alive
    Content-Length: 170
    Content-Type: application/json; charset=utf-8
    Date: Thu, 09 May 2019 15:24:42 GMT
    Docker-Distribution-Api-Version: registry/2.0
    Www-Authenticate: Bearer realm="https://docker-auth.elastic.co/auth",service="token-service",scope="repository:elasticsearch/elasticsearch:pull"
    X-Content-Type-Options: nosniff
    
    {
        "errors": [
            {
                "code": "UNAUTHORIZED",
                "detail": [
                    {
                        "Action": "pull",
                        "Class": "",
                        "Name": "elasticsearch/elasticsearch",
                        "Type": "repository"
                    }
                ],
                "message": "authentication required"
            }
        ]
    }
    

    Use the information in the WWW-Authenticate to request a token for the given service and scope:

    http "https://docker-auth.elastic.co/auth?service=token-service&scope=repository:elasticsearch/elasticsearch:pull"                                                                            (567ms)  
    HTTP/1.1 200 OK
    Connection: keep-alive
    Content-Length: 790
    Content-Type: application/json
    Date: Thu, 09 May 2019 15:25:37 GMT
    
    {
        "token": "some-long-token"
    }
    

    Finally, make the request using the token:

    http -v https://docker.elastic.co/v2/elasticsearch/elasticsearch/tags/list 'Authorization: Bearer some-long-token'
    HTTP/1.1 200 OK
    Connection: keep-alive
    Content-Length: 1765
    Content-Type: application/json; charset=utf-8
    Date: Thu, 09 May 2019 15:26:18 GMT
    Docker-Distribution-Api-Version: registry/2.0
    X-Content-Type-Options: nosniff
    
    {
        "name": "elasticsearch/elasticsearch",
        "tags": [
            "5.0.0-731e78df",
            "5.0.0-86a0b164",
            "5.0.0-alpha5",
            "5.0.0-beta1",
            "5.0.0-ccd69424",
            "5.0.0-rc1",
            "5.0.0",
            ...
            ...
            ...