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:
"Accept: application/vnd.docker.distribution.manifest.v2+json"added to the header on the call
The call returns header key
Docker-Content-Digestwith a value such as
Using that value from step 2, run the delete call:
Registry API returns
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?
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
When I delete the
myimage folder (from
docker/registry/v2/repositories/myimage) then the repository is no longer shown in the
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
_layerssubdirectory and why the garbage collector doesn't clean up that directory the same it does with manifests and blobs.