{"id":13416501,"url":"https://github.com/hcguersoy/cleanreg","last_synced_at":"2025-10-11T14:35:47.795Z","repository":{"id":15335825,"uuid":"77925337","full_name":"hcguersoy/cleanreg","owner":"hcguersoy","description":"A small tool to clean up Docker Registries (v2).","archived":false,"fork":false,"pushed_at":"2022-09-03T17:43:40.000Z","size":155,"stargazers_count":59,"open_issues_count":2,"forks_count":18,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-10-11T14:35:44.973Z","etag":null,"topics":["docker","docker-image","docker-registry","garbage-collection","python","registry","registry-server"],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hcguersoy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-01-03T14:42:17.000Z","updated_at":"2025-07-09T23:24:24.000Z","dependencies_parsed_at":"2022-07-20T21:32:15.658Z","dependency_job_id":null,"html_url":"https://github.com/hcguersoy/cleanreg","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/hcguersoy/cleanreg","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hcguersoy%2Fcleanreg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hcguersoy%2Fcleanreg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hcguersoy%2Fcleanreg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hcguersoy%2Fcleanreg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hcguersoy","download_url":"https://codeload.github.com/hcguersoy/cleanreg/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hcguersoy%2Fcleanreg/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279007448,"owners_count":26084313,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-11T02:00:06.511Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","docker-image","docker-registry","garbage-collection","python","registry","registry-server"],"created_at":"2024-07-30T21:00:59.814Z","updated_at":"2025-10-11T14:35:47.779Z","avatar_url":"https://github.com/hcguersoy.png","language":"Shell","funding_links":[],"categories":["Docker Images","Shell"],"sub_categories":["Registry"],"readme":"\n# Registry Cleaner\n\n[![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg)](https://stand-with-ukraine.pp.ua)\n[![cleanreg](https://github.com/hcguersoy/cleanreg/actions/workflows/build-publish.yaml/badge.svg)](https://github.com/hcguersoy/cleanreg/actions/workflows/build-publish.yaml)\n\nThis is a small tool to delete tags, or, to be more correct, delete image manifests, from a Docker Registry implementing the API v2.\n\nPlease be aware of that this is a soft delete. You've to run the registry garbage collection after this tool has been applied.\n\nInformation about the needed garbage collection is described at [https://docs.docker.com/registry/garbage-collection/](https://docs.docker.com/registry/garbage-collection/).\n\n## Credits and Contributors\n\nThe list of contributors can be found in the [authors list](https://github.com/hcguersoy/cleanreg/blob/master/cleanreg.py#L18)\nin the python code.\n\nThis project uses [shunit2](https://github.com/kward/shunit2) by [Kate Ward](https://github.com/kward).\n\n## History\n\n* v0.8.1 - Removes possible _Zulu_-Time marker from retrieved creation times (thanks to @slamdev for his [PR16](https://github.com/hcguersoy/cleanreg/pull/16))\n* v0.8.0 - Finally find the time to migrate to Python 3 and Github Actions. This comes this many changes in the code and the surrounding build system. Support for `linux\\arm64` added.\n* v0.7.1 - Added a `--skip-tls-verify` attribute - this version was not released\n* v0.7 - This is a release which breaks some stuff (configuration file is now yaml based), adding new options for keeping images (e.g. `--since`, `--regex`) (thanks to @JulianSauer for his [PR10](https://github.com/hcguersoy/cleanreg/pull/10))\n* v0.6 - add `-cf` flag which allows to clean up all repos in a registry (thanks @kekru for his PR)\n* v0.5 - fix for issue [#8](https://github.com/hcguersoy/cleanreg/issues/8) which resulted in deleting more layers then intended; performance improvements; added `--metadata-workers` attribute\n* v0.4.1 - added `--assume-yes` and deprecated `--quiet` flag\n* v0.4 - added support for basic auth secured registry servers, introducing `--basicauth-user` and `--basicauth-pw` (thanks to @kekru for his pull request)\n* v0.3 - fixing deletion if a digest is associated with multiple tags, introducing the `--ignore-ref-tags` flag.\n* v0.2 - added support for registry server using self signed certificates\n* v0.1 - first version with basics\n\n## Prerequisites and supported Platform\n\nYou need Docker and a Docker registry system which implements the Registry API v2.\nFor Docker Registry v2 API specification see [https://docs.docker.com/registry/spec/api/](https://docs.docker.com/registry/spec/api/).\n\nBe sure to configure your registry server to allow deletion (see [https://docs.docker.com/registry/configuration/#/delete](https://docs.docker.com/registry/configuration/#/delete)).\n\n## Usage\n\nDownload the file _cleanreg.py_ or clone this repository to a local directory or pull the docker image.\nBeginning with version `v0.8.0`, images are supported for `linux/amd64` and (this is new) `linux\\arm64`.\nThis is the suggested way to run `cleanreg`!\n\n```shell\ndocker pull hcguersoy/cleanreg:v0.8.1\n```\n\nThe image is hosted here: [https://hub.docker.com/r/hcguersoy/cleanreg/](https://hub.docker.com/r/hcguersoy/cleanreg/ \"\")\n\n_Hint:_ `latest` tag is not supported (you know, `latest` is evil :imp:).\n\nTo get a immediate help simply run it without any parameters:\n\n```shell\n$ docker run --rm hcguersoy/cleanreg:v0.8.1\nusage: cleanreg.py [-h] [-v] -r REGISTRY [-p] [-y] [-q] [-n REPONAME:TAG]\n                   [-k KEEPIMAGES] [-re] [-d DATE]\n                   [-f REPOSFILE] [-c CACERT] [-sv] [-i] [-u BASICAUTHUSER]\n                   [-pw BASICAUTHPW] [-w MD_WORKERS]\n\nRemoves images on a docker registry (v2).\n\noptional arguments:\n  -h, --help            show this help message and exit\n  -v, --verbose         The verbosity level. Increase verbosity by multiple\n                        usage, e.g. -vvv .\n  -r REGISTRY, --registry REGISTRY\n                        The registry server to connect to, e.g.\n                        http://1.2.3.4:5000\n  -p, --proxy           Use system level proxy settings accessing registry\n                        server if set. By default, the registry server will be\n                        accessed without a proxy.\n  -y, --yes, --assume-yes\n                        If set no user action will appear and all questions\n                        will be answered with YES\n  -q, --quiet           [deprecated] If set no user action will appear and all\n                        questions will be answered with YES\n  -n REPONAME, --reponame REPONAME:TAG\n                        The name of the repo which should be cleaned up. Tags\n                        are optional.\n  -cf, --clean-full-catalog\n                        If set all repos of the registry will be cleaned up,\n                        considering the -k, -re and -d options.\n                        These can be overridden for each repo in the repofile (-f).\n  -k KEEPIMAGES, --keepimages KEEPIMAGES\n                        Amount of images (not tags!) which should be kept for\n                        the given repo  (if -n is set) or for each repo of the\n                        registry (if -cf is set).\n  -re, --regex\n                        Interpret tagnames as regular expressions for the given\n                        repo  (if -n is set) or for each repo of the registry (if\n                        -cf is set).\n  -s DATE, --since DATE\n                        Keeps images which were created since then for\n                        the given repo  (if -n is set) or for each repo of the\n                        registry (if -cf is set).\n                        Format: YYYYMMDD, YYYYMMDDThhmmss, YYYY-MM-DD or YYYY-MM-DDThh:mm:ss\n  -f REPOSFILE, --reposfile REPOSFILE\n                        A yaml file containing the list of Repositories with\n                        additional information regarding tags, dates and how many\n                        images to keep.\n                        Format: REPONAME:\n                            tag: TAG\n                            keepimages: KEEPIMAGES\n                            keepsince: DATE\n  -c CACERT, --cacert CACERT\n                        Path to a valid CA certificate file. This is needed if\n                        self signed TLS is used in the registry server.\n  -sv, --skip-tls-verify\n                        If set insecure TLS is allowed, so no need for\n                        a valid cert to verify.\n  -i, --ignore-ref-tags\n                        Ignore a digest if it is referenced multiple times in\n                        the whole registry server. In this case, a list of all\n                        repositories and their images will be retrieved which\n                        can be time and memory consuming. ATTENTION: the\n                        default is False so an image will be deleted even it\n                        is referenced multiple times.\n  -u BASICAUTHUSER, --basicauth-user BASICAUTHUSER\n                        The username, if the registry is protected with basic\n                        auth\n  -pw BASICAUTHPW, --basicauth-pw BASICAUTHPW\n                        The password, if the registry is protected with basic\n                        auth\n  -w MD_WORKERS, --metadata-workers MD_WORKERS\n                        Parallel workers to retrieve image metadata. Default\n                        value is 6.\n\n```\n\nIf you've to use a configuration file (parameter `-f`) you should mount that file into your container:\n\n```shell\ndocker run --rm -it -v $(pwd)/cleanreg-example.conf:/cleanreg-example.yaml hcguersoy/cleanreg:\u003cversion\u003e -r  http://192.168.56.2:5000 -f cleanreg-example.yaml -i\n```\n\nAs an alternative, you can create your own image, inheriting from `cleanreg`:\n\n```shell\nFROM hcguersoy/cleanreg:\u003cversion\u003e\nADD myconfig.yaml /config.yaml\n```\n\n## Examples\n\n\u003e :exclamation: It is strongly recommended that you use the `-i` flag even it is more time and memory consuming. If not you can delete images / layers which you not wanted to delete because registry itself doesn't check if a digest is referenced by multiple tags!\n\nCleaning up a single repository called mysql on registry server _192.168.56.2:5000_ and keeping 5 of the latest images:\n\n```shell\ndocker run --rm -it hcguersoy/cleanreg:\u003cversion\u003e -r http://192.168.56.2:5000 -n mysql -k 5\n```\n\nBe aware that you don't keep here the five last tags but digests/images. As a digest can be associated with multiple tags this can result in deletion of images which you not intended in!\nAgain: to be secure use the `-i` flag:\n\n```shell\ndocker run --rm -it hcguersoy/cleanreg:\u003cversion\u003e -r http://192.168.56.2:5000 -n mysql -k 5 -i\n```\n\nSame as above but ignore images which are associated with multiple tags.\n\n```shell\ndocker run --rm -it hcguersoy/cleanreg:\u003cversion\u003e -r http://192.168.56.2:5000 -n mysql:latest -i\n```\n\nWill only delete the image mysql which is tagged as latest.\n\n```shell\ndocker run --rm -it hcguersoy/cleanreg:\u003cversion\u003e -r http://192.168.56.2:5000 -n mysql:.*temp.* -re -d 2022-01-01 -k 5 -i\n```\n\nRemoves all images that contain the word _\"temp\"_ in their tag's and if they were created before 2022 but at least 5 will be kept in total.\n\n```shell\ndocker run --rm -it hcguersoy/cleanreg:\u003cversion\u003e -r http://192.168.56.2:5000 -n myalpine -k 50 -i -w 12\n```\n\nIf you have a very large registry and enough bandwidth you can increase the parallel workers to retrieve the image metadata. The default is _6_. Be aware that you can generate a _DoS_ on your registry server by increasing to much.\n\nCleaning up all repositories of the registry:\n\n```shell\ndocker run --rm -it hcguersoy/cleanreg:\u003cversion\u003e -r http://192.168.56.2:5000 -cf -k 5 -i\n```\n\nThis will clean up all repositories, keeping 5 images per repository.\n\nCleaning up multiple repositories defined in a configuration file:\n\n```shell\ndocker run --rm -it \\\n        -v $(pwd)/cleanreg-example.conf:/cleanreg-example.yaml \\\n       hcguersoy/cleanreg:\u003cversion\u003e  \\\n       -r http://192.168.56.2:5000 \\\n       -f /cleanreg-example.yaml \\\n       -re \\\n       -i\n```\n\nThe configuration file has the format\n\n```yaml\n\u003crepository name\u003e:\n    tag: \u003ctag\u003e\n    keepimages: \u003cnumber of images to keep\u003e\n    keepsince: \u003cdate\u003e\n```\n\nThe values for `tag`, `keepimages` and `keepsince` are optional. If the tag should be parsed as a regular expression use the `-re` flag as shown above. A simple example for the configuration file:\n\n```yaml\nconsul:\n  tag: OnlyThisTag\n  keepimages: 20\n  keepsince: 2000-12-24T12:31:59\nelasticsearch:\n  keepimages: 20\n  keepsince: 20000101\ndummybox:\n  keepimages: 0\n```\n\nThe configuration file can be used together with the clean-full-catalog option:\n\n```shell\n./cleanreg.py -r http://192.168.56.2:5000 -cf -d 20180101 -f cleanreg-example.conf -i\n```\n\nThis will clean the repositories with images to keep as defined in the configuration file and it will additionally clean all other repositories of the registry, keeping images per repository that were created since 2018.\n\nThere is a simple script added to create multiple image tags (based on `busybox`) on your registry server.\n\nIf you have installed a _semi secure_ registry server using TLS and self signed certificates you have to provide the path to the CA certificate file:\n\n```shell\n./cleanreg.py -r https://192.168.56.3:5000 -c /my/certificates/ca.pem -f cleanreg-example.conf -i\n```\n\nIf you run _cleanreg_ in a container you should not forget to mount the certificate file into the container like the configuration file above.\nAlternatively you can set the option `--skip-tls-verify`. In this case, you don't need to provide a certificate.\n\n\u003e :exclamation: be aware that this should only used for (local) testing and development but not for productive environments.\n\nIf your registry is protected with basic auth and the username is `test` and the password is `secret`, you have to pass these credentials to _cleanreg_.\n\n```shell\n./cleanreg.py -r https://192.168.56.3:5000 -u test -pw secret -f cleanreg-example.conf\n```\n\n\u003e :exclamation: if you provide the password this way, the password will be saved in your shell history in cleartext!\n\n## Running Garbage Collection\n\nExample on running the garbage collection:\n\n```shell\n$ docker run --rm \\\n  -v /docker/registry2:/var/lib/registry:rw \\\n  registry:latest bin/registry \\\n  garbage-collect /etc/docker/registry/config.yml\n```\n\nThis maps the local directory /docker/registry2 into the container, and calls the garbage collection.\nThe pointed config file is the default configuration.\nThe registry itself should be stopped before running this.\n\n## Contribution\n\nFeel free to contribute your changes as a PR. Please ensure that the tests run without errors and provide tests for additional functionality.\n\nIt may take some time until I get aware of your PR and some time, too, until I merge it. Sorry for this.\n\nThis tool was initially implemented and tested on Ubuntu Linux 16.04 and on MacOS 10.13 using Python 2.7 and migrated to Python 3.10.\nIt is developed and tested currently against Docker Registry version [v2.8.1](https://github.com/distribution/distribution/releases/tag/v2.8.1) on macOS 12 (arm64). The testing with older versions is dropped with version 0.8.1.\nIt should work with older registry versions which are supporting the API, but they are not tested anymore.\n\nYou need to install the Python modules _requests_ and _PyYAML_:\n\n```shell\n$ pip install requests PyYAML\n```\n\nBe sure to configure your registry server to allow deletion (see [https://docs.docker.com/registry/configuration/#delete](https://docs.docker.com/registry/configuration/#delete)).\n\n### Run tests locally\n\nPrerequisites:\n\n* Bash\n* Locally installed Docker engine. Remote execution is not yet implemented. Runs with [Rancher Desktop](https://rancherdesktop.io) on macOS fine (configured to use _dockerd_ as runtime).\n\nYou can run all tests, with the _runAllTests.sh_ script:\n\n```shell\ncd test\n./runAllTests.sh\n```\n\nThis will run all tests and repeat them for different versions of the Docker Registry.\n\nTo run a single test, change to the `test/tests` directory and run a test script:\n\n```shell\ncd test/tests\n./simple_clean.sh\n```\n\nBy default the test will start the Docker Registry from Docker Hub with the tag `latest`.\nTo specify another registry version, set it using the environment variable `REGISTRYTAG`.\n\n```shell\ncd test/tests\nexport REGISTRYTAG=2.5.1\n./simple_clean.sh\n```\n\n### GitHub Actions\n\nAfter pushing to `master` or a branch `feature\\*` or `pr\\*` a GitHub Action will be triggered which runs the tests defined in `test/runAllTests.sh`. If one of these tests fail, the action will fail, too.\nIf the build was triggered due to the creation of a release, a GitHub Action will be triggered, too. In this case, after running successfully the tests, the Docker image will be build with the help of _buildx_.\nCurrently, two kinds of architectures are supported: `linux/amd64` and `linux/arm64`.\nThe later one could be used on Apple Silicon systems this the according runtime, e. g. Rancher Desktop.\n\n\u003e Due to the lack of knowledge regarding other ARM systems (e. g. Raspberry Pi) you are very welcome to provide a PR.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhcguersoy%2Fcleanreg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhcguersoy%2Fcleanreg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhcguersoy%2Fcleanreg/lists"}