Following the official documentation (https://docs.docker.com/registry/spec/api/#deleting-an-image) I have been able to successfully delete an image. As expected, after deleting, the image can no longer be pulled nor its manifest called via API.
I feel like I've got the hard part done, however the problem is that the repo is still listed under /v2/_catalog
after the deletion is finished. I'm trying to fully purge the registry.
Here is my registry compose file:
registry:
image: registry:2.5.2
container_name: registry-test
ports:
- 5007:5000
environment:
REGISTRY_STORAGE: s3
REGISTRY_HTTP_TLS_CERTIFICATE: /etc/cert.crt
REGISTRY_HTTP_TLS_KEY: /etc/cert.key
REGISTRY_STORAGE_S3_ACCESSKEY: ******
REGISTRY_STORAGE_S3_SECRETKEY: ******
REGISTRY_STORAGE_S3_REGION: us-west-1
REGISTRY_STORAGE_S3_BUCKET: ******
REGISTRY_STORAGE_S3_SECURE: "true"
REGISTRY_STORAGE_DELETE_ENABLED: "true"
volumes:
- /dockerdata/volumes/registry-test/etc/cert.crt:/etc/cert.crt
- /dockerdata/volumes/registry-test/etc/cert.key:/etc/cert.key
restart: unless-stopped
Here is the high-level method on what I did to delete the image:
Gather image digest:
HEAD https://myprivateregistry:5001/v2/myimage/manifests/mytag
with"Accept: application/vnd.docker.distribution.manifest.v2+json"
added to the header on the callThe call returns header key
Docker-Content-Digest
with a value such assha256:b57z31xyz0f616e65f106b424f4ef29185fbd80833255d79dabc73b8eb873bd
Using that value from step 2, run the delete call:
DELETE https://myprivateregistry:5001/v2/myimage/manifests/sha256:b57z31xyz0f616e65f106b424f4ef29185fbd80833255d79dabc73b8eb873bd
Registry API returns
202 Accepted
Run garbage collection manually:
registry garbage-collect /etc/docker/registry/config.yml
Garbage collector deletes the associated blobs from disk (log omitted here, but it successfully deletes the blobs)
At this point I can confirm the blobs are completely deleted from disk and I can no longer call image details (like in step 1 above) so I thought I was done.
However, when running: /v2/_catalog
my associated repo still lists (even though there are no images within it)! Obviously it cannot pull or be used, but how can I fully remove that repo from that list now that it has no images associated with it?
I don't see anywhere how to properly remove this on the API documentation page. Perhaps I'm missing it somewhere?
EDIT -
I wanted to add some more info on how the registry looks before and after the above deletion takes place.
Before the Delete Operation Above:
docker/registry/v2/repositories/myimage/_manifests/revisions/...
docker/registry/v2/repositories/myimage/_manifests/tags/...
docker/registry/v2/repositories/myimage/_layers/sha256/... (5 layers listed)
docker/registry/v2/blobs/sha256/...
After the Delete Operation Above:
docker/registry/v2/repositories/myimage/_layers/sha256/... (5 layers listed)
So the only thing left over is the _layers
directory with the same 5x layers listed. This seems to be the reason why it's still listed on _catalog
When I delete the myimage
folder (from docker/registry/v2/repositories/myimage
) then the repository is no longer shown in the _catalog
This seems to be a method to purge it from the _catalog
listing. However - what if an image has 2x tags, yet only 1 is deleted - is there a reason to delete anything from _layers
in that case? How would that be handled with multiple versions of an image? Obviously I can't just clobber the _layers
directory as the final method since, in the real world, there will be many tagged versions of an image. So this needs to be done intelligently.
I am simply finding it hard to find any documentation on the maintenance/upkeep of the Docker registry nor the schema for the
_layers
subdirectory and why the garbage collector doesn't clean up that directory the same it does with manifests and blobs.
After much research, there is no current method to remove the catalog entries fully via API only.
This means that the entire image is deleted. Deletion of tags is in an open PR for a future version of the Registry (https://github.com/docker/distribution/pull/2169)
What this means in regards to this question is that the proper method is to delete the image from the repo list is exactly as you assumed. Remove it from disk. (Such as
rm -r v2/repositories/myimage
wheremyimage
is the image name that you deleted via API.)It will then be removed from the repo list in
_catalog
and you're finished with your deletion process. There is no need to restart anything like another answer mentioned.When the ability to delete specific tags from the registry is added, then this procedure will change. For now it's all or nothing.
Reference:
https://forums.docker.com/t/delete-repository-from-v2-private-registry/16767/5
https://github.com/docker/distribution/pull/2169
https://docs.docker.com/registry/spec/api/