This is expected behavior, and not specific to DOCR, but it is a bit confusing.
Images in a container registry can be accessed in two ways: by tag or by digest. The digest is an immutable reference to the image based on its contents, and is the “canonical” way to reference an image. A tag is a mutable, human-friendly reference to a digest. You can pull (or push) images by digest using
docker pull registry.digitalocean.com/my-registry/my-repo@sha256:<digest>.
When you push a new image using an existing tag, the tag gets updated but the old image doesn’t go away: it’s still accessible by its digest. DOCR doesn’t automatically clean up untagged images, since it’s completely valid to reference them directly by their digests.
To reduce your storage usage, you’ll need to clean up the untagged images and then run garbage collection. You can delete an image by digest using the
doctl registry repo delete-manifest command, or with tools such as reg. Unfortunately, at the moment there isn’t a great way to see the digests of untagged images in your registry (see below for future work that will address this). Once you’ve deleted images by digest, you can run
doctl registry gc start to kick off garbage collection, which will clean up any layers that are no longer in use by any image.
I’d suggest modifying your workflow a bit to make cleanup easier. If you push images with unique tags (e.g., based on the git commit hash or some other unique identifier at build time), you can clean them up more easily after you push a new version. You can still use the latest tag additionally, and doing so won’t increase your storage usage at all. For example, if building from a git repository you could do:
$ REV=$(git rev-parse HEAD)
$ docker build -t registry.digitalocean.com/my-registry/my-repo:$REV -t registry.digitalocean.com/my-registry/my-repo:latest .
$ docker push registry.digitalocean.com/my-registry/my-repo:$REV
$ docker push registry.digitalocean.com/my-registry/my-repo:latest # no new layers to push, should be very fast
You can then easily clean up old images with
doctl and run GC to clean up unused layers:
$ doctl registry repo list-tags my-repo
$ doctl registry repo delete-manifest my-repo sha256:<digest>
$ doctl registry gc start
We are working on a few changes to make managing your storage space easier in the future:
- We’re working on showing untagged images in the control panel and doctl, so you can delete them directly from there without knowing their digests.
- We’re also working on garbage collection previews, to let you know ahead of time how much space you would save by running garbage collection.
- On our longer-term roadmap we have image lifecycle configuration. This would allow you to configure automatic cleanup of untagged images.
Hope this is helpful - please do reply if you have any other questions about DOCR!