Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use the Docker Registry API V2 to delete an image from a private registry?

Given a Docker Registry at localhost:5000, how can I use the Docker Registry HTTP API V2 and curl to delete busybox:latest that has the following manifest header and manifest:

derek@derekmahar-ubuntu-512mb-tor1-01:~/Projects/docker-registry$ curl --head --request GET http://localhost:5000/v2/busybox/manifests/latest
HTTP/1.1 200 OK
Content-Length: 2561
Content-Type: application/vnd.docker.distribution.manifest.v1+prettyjws
Docker-Content-Digest: sha256:e45f25b1760f616e65f106b424f4ef29185fbd80822255d79dabc73b8eb715ad
Docker-Distribution-Api-Version: registry/2.0
Etag: "sha256:e45f25b1760f616e65f106b424f4ef29185fbd80822255d79dabc73b8eb715ad"
X-Content-Type-Options: nosniff
Date: Wed, 04 May 2016 16:10:00 GMT

derek@derekmahar-ubuntu-512mb-tor1-01:~/Projects/docker-registry$ curl --request GET http://localhost:5000/v2/busybox/manifests/latest
{
   "schemaVersion": 1,
   "name": "busybox",
   "tag": "latest",
   "architecture": "amd64",
   "fsLayers": [
      {
         "blobSum": "sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4"
      },
      {
         "blobSum": "sha256:385e281300cc6d88bdd155e0931fbdfbb1801c2b0265340a40481ee2b733ae66"
      }
   ],
   "history": [
      {
         "v1Compatibility": "{\"architecture\":\"amd64\",\"config\":{\"Hostname\":\"156e10b83429\",\"Domainname\":\"\",\"User\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":null,\"Cmd\":[\"sh\"],\"Image\":\"56ed16bd6310cca65920c653a9bb22de6b235990dcaa1742ff839867aed730e5\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"OnBuild\":null,\"Labels\":{}},\"container\":\"5f8098ec29947b5bea80483cd3275008911ce87438fed628e34ec0c522665510\",\"container_config\":{\"Hostname\":\"156e10b83429\",\"Domainname\":\"\",\"User\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":null,\"Cmd\":[\"/bin/sh\",\"-c\",\"#(nop) CMD [\\\"sh\\\"]\"],\"Image\":\"56ed16bd6310cca65920c653a9bb22de6b235990dcaa1742ff839867aed730e5\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"OnBuild\":null,\"Labels\":{}},\"created\":\"2016-03-18T18:22:48.810791943Z\",\"docker_version\":\"1.9.1\",\"id\":\"437595becdebaaaf3a4fc3db02c59a980f955dee825c153308c670610bb694e1\",\"os\":\"linux\",\"parent\":\"920777304d1d5e337bc59877253e946f224df5aae64c72538672eb74637b3c9e\"}"
      },
      {
         "v1Compatibility": "{\"id\":\"920777304d1d5e337bc59877253e946f224df5aae64c72538672eb74637b3c9e\",\"created\":\"2016-03-18T18:22:48.262403239Z\",\"container_config\":{\"Cmd\":[\"/bin/sh -c #(nop) ADD file:47ca6e777c36a4cfffe3f918b64a445c8f32300deeb9dfa5cc47261bd7b75d21 in /\"]}}"
      }
   ],
   "signatures": [
      {
         "header": {
            "jwk": {
               "crv": "P-256",
               "kid": "RVEO:MXL3:ZYLW:BFGB:QAKI:SIKZ:JOVR:U7AP:2LGY:4SSF:MSV4:LND7",
               "kty": "EC",
               "x": "ZFyhNUInMwlVmFKzz-e-o_tzMd01ZdCj6LyGV4dnT5Y",
               "y": "3a0BcWa0h60tTGHYhUI4ziKisRk6b4JtvqbmL9kKy6E"
            },
            "alg": "ES256"
         },
         "signature": "BVWioJafWmMrUBBi9meRy9CUQYdsZgwkY01ipT1HInXofVXCIZmNMq7EFEl4A88pMZsf7DHZS2dyFeFjj-QP1Q",
         "protected": "eyJmb3JtYXRMZW5ndGgiOjE5MTQsImZvcm1hdFRhaWwiOiJDbjAiLCJ0aW1lIjoiMjAxNi0wNS0wNFQxNjoxMzo0M1oifQ"
      }
   ]
}

Docker Registry complains with "HTTP/1.1 404 Not Found" and "MANIFEST_UNKNOWN" when I attempt to DELETE the image digest:

derek@derekmahar-ubuntu-512mb-tor1-01:~/Projects/docker-registry$ curl --request DELETE http://localhost:5000/v2/busybox/manifests/sha256:e45f25b1760f616e65f106b424f4ef29185fbd80822255d79dabc73b8eb715ad
{"errors":[{"code":"MANIFEST_UNKNOWN","message":"manifest unknown"}]}
like image 383
Derek Mahar Avatar asked May 04 '16 16:05

Derek Mahar


People also ask

How do I remove an image from docker repository?

Docker rmi To remove the image, you first need to list all the images to get the Image IDs, Image name and other details. By running simple command docker images -a or docker images . After that you make sure which image want to remove, to do that executing this simple command docker rmi <your-image-id> .

Does docker RMI Remove from registry?

This does not remove images from a registry. You cannot remove an image of a running container unless you use the -f option. To see all images on a host use the docker image ls command.


3 Answers

PLEASE NOTE: This API endpoint is only implemented in later versions of v2 registry!

There is an internal garbage collection process which deletes images in the registry, but which is not (yet) accessible via the v2 registry API. This feature looks like it has a lot of recent movement, so this information could change.

According to the API spec, you've got to grab the image digest in order to run a DELETE against it. Read the spec carefully and notice the part about the required header when asking for the right image digest ("Note When deleting a manifest from a registry version 2.3 or later, the following header must be used when HEAD or GET-ing the manifest to obtain the correct digest to delete: Accept: application/vnd.docker.distribution.manifest.v2+json")

curl -v -u "[email protected]:passw0rd" -H "Accept: application/vnd.docker.distribution.manifest.v2+json" -X HEAD https://registry.example.com/v2/derek/busybox/manifests/latest

When you do that, you're going to be paying special attention to the Docker-Content-Digest header. In your particular request, that full header looks like this:

Docker-Content-Digest: sha256:e45f25b1760f616e65f106b424f4ef29185fbd80822255d79dabc73b8eb715ad

Now with that digest you should be able to plug it into the format described by the API you linked:

DELETE /v2/<name>/manifests/<reference>

And to use the example I used above, but with your digest, the curl looks like this:

curl -u "[email protected]:passw0rd" -X DELETE https://registry.example.com/v2/derek/busybox/manifests/sha256:e45f25b1760f616e65f106b424f4ef29185fbd80822255d79dabc73b8eb715ad

Then you should get a 202 Accepted response code indicating successful deletion.

You can also try the short script from this gist:

registry='localhost:5000'
name='my-image'
curl -v -sSL -X DELETE "http://${registry}/v2/${name}/manifests/$(
    curl -sSL -I \
        -H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
        "http://${registry}/v2/${name}/manifests/$(
            curl -sSL "http://${registry}/v2/${name}/tags/list" | jq -r '.tags[0]'
        )" \
    | awk '$1 == "Docker-Content-Digest:" { print $2 }' \
    | tr -d $'\r' \
)"
like image 100
L0j1k Avatar answered Oct 16 '22 13:10

L0j1k


You may also need to enable deletion in the config file.

See https://docs.docker.com/registry/configuration/#/delete

like image 29
Quentin Stafford-Fraser Avatar answered Oct 16 '22 12:10

Quentin Stafford-Fraser


I had this exact same problem. The MANIFEST_UNKNOWN error happens when using a valid digest, but not a digest that refers to the manifest. You MUST MUST MUST use '-H "Accept: application/vnd.docker.distribution.manifest.v2+json' to get the correct Docker-Content-Digest value that refers to manifest.

$ curl -s -I http://$REGISTRY/v2/myapp/manifests/1.0.0 | awk '/^Docker-Content-Digest/ {print $2}'
sha256:c1102294980e4ad2563a7ba65e9192ec3980dbb1f863fd1f81adcb95bc6e0c2a
$
$ curl -s -X DELETE http://$REGISTRY/v2/myapp/manifests/sha256:c1102294980e4ad2563a7ba65e9192ec3980dbb1f863fd1f81adcb95bc6e0c2a
{"errors":[{"code":"MANIFEST_UNKNOWN","message":"manifest unknown"}]}

Versus

$ curl -s -I -H "Accept: application/vnd.docker.distribution.manifest.v2+json" http://$REGISTRY/v2/myapp/manifests/1.0.0 | awk '/^Docker-Content-Digest/ {print $2}'
sha256:5403b52afdba954349746c60f4e6dc18d2a6ab414333c8ab4b0928126e63371f
$
$ curl -s -X DELETE http://$REGISTRY/v2/myapp/manifests/sha256:5403b52afdba954349746c60f4e6dc18d2a6ab414333c8ab4b0928126e63371f
$ # successfully deleted, no error
like image 24
Jeremy Lisenby Avatar answered Oct 16 '22 14:10

Jeremy Lisenby