Given docker repositories repo1
and repo2
.
$ curl -X GET localhost:5000/v2/_catalog
{"repositories":["repo1", "repo2"]}
I want to remove repository repo1
so _catalog
does not list repo1
, like
$ curl -X GET localhost:5000/v2/_catalog
{"repositories":["repo2"]}
Currently, repository repo1
only has the default "latest"
image tag
$ curl -X GET localhost:5000/v2/repo1/tags/list
{"name":"repo1","tags":["latest"]}
(Maybe that affects being able to delete repo1
?)
The following commands returned 404 page not found
:
$ curl -X DELETE localhost:5000/v1/repositories/repo1
$ curl -X DELETE localhost:5000/v2/repositories/repo1
$ curl -X DELETE localhost:5000/v2/repo1
And the following returned {"errors":[{"code":"UNSUPPORTED","message":"The operation is unsupported."}]}
$ curl -X DELETE localhost:5000/v2/repo1/manifests/latest
The remote docker-registry is registry/2.0
curl -vX GET localhost:5000/v2/
< HTTP/1.1 200 OK
...
< Docker-Distribution-Api-Version: registry/2.0
...
and
$ /bin/registry github.com/docker/distribution v2.4.1
Go to the Container Registry page. Click on the image name to see version(s) of that image. In the registry, check the box next to the version(s) of the image that you want to delete. Click DELETE on the top of the page.
It's also worth pointing out that the Docker Hub and other third party repository hosting services are called “registries”. A registry stores a collection of repositories.
by enabling DELETE API you're only able to delete the TAG not the whole repository from v2/_catalog
.
in order to do this, you should:
1. enable DELETE API:
1.1 by config.yml
: storage.delete.enabled:true
1.2 by env: -e REGISTRY_STORAGE_DELETE_ENABLED=true
2. get the tag reference via GET /v2/<name>/manifests/<tag>
(don't forget to have Header Accept: application/vnd.docker.distribution.manifest.v2+json
).
in response headers, you have docker-content-digest: <sha256:xxx>
3. send DELETE /v2/<name>/manifests/<sha256:xxx>
4. run garbage collector: bin/registry garbage-collect /etc/docker/registry/config.yml
5. remove files: rm -r /var/lib/registry/docker/registry/v2/repositories/<name>/<tag>
finally: now you can see
curl -X GET localhost:5000/v2/_catalog
{"repositories":["repo2", "repo3"]}
ps.
consequences of 5: https://github.com/docker/distribution/issues/2983#issuecomment-530251232
There is no API to delete a repository. You need to delete individual tags or manifests within the repository. And until OCI's distribution-spec, there wasn't even an API to delete tags, you need to delete image manifests by digest, which deletes all tags pointing to that same digest.
To delete manifests, first ensure that you have enabled deletion according to this documentation before attempting anything. In your configuration of the registry, you would add the following section:
delete:
enabled: true
That can also be set by starting your registry container with the REGISTRY_STORAGE_DELETE_ENABLED=true
environment variable specified.
Then you can call the manifest delete API:
curl -X DELETE \
-s "https://registry.example.org/v2/${repo}/manifests/${sha}"
If you want a wrapper around this to handle auth, and even support tag deletion, see regclient's regctl CLI that I've written. Google's crane and RedHat's skopeo may also provide this.
Once the manifests are deleted, you still need to clean the other items the manifest pointed to with a garbage collection (this needs to be done when no writes are occurring):
docker exec registry /bin/registry garbage-collect /etc/docker/registry/config.yml --delete-untagged
That said, you'll still reach the point where the repository itself is not removed. You can delete the entire directory from the filesystem of the registry. But I would recommend getting support for this implemented from the project. See this issue for more details on getting the capability added to the official registry image.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With