{"id":15222039,"url":"https://github.com/googlecloudplatform/gcr-cleaner","last_synced_at":"2025-05-16T08:04:47.427Z","repository":{"id":39099482,"uuid":"182618276","full_name":"GoogleCloudPlatform/gcr-cleaner","owner":"GoogleCloudPlatform","description":"Delete untagged image refs in Google Container Registry or Artifact Registry","archived":false,"fork":false,"pushed_at":"2024-09-30T17:09:13.000Z","size":569,"stargazers_count":808,"open_issues_count":1,"forks_count":113,"subscribers_count":27,"default_branch":"main","last_synced_at":"2025-05-16T08:04:40.092Z","etag":null,"topics":["artifact-registry","cloud-run","cloud-scheduler","container-registry","google-cloud-run","google-cloud-scheduler","google-container-registry"],"latest_commit_sha":null,"homepage":"","language":"Go","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/GoogleCloudPlatform.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-04-22T03:41:42.000Z","updated_at":"2025-01-22T19:10:08.000Z","dependencies_parsed_at":"2023-02-05T20:02:15.310Z","dependency_job_id":"edd25715-d557-42cd-9f26-e1cd69529e7e","html_url":"https://github.com/GoogleCloudPlatform/gcr-cleaner","commit_stats":{"total_commits":116,"total_committers":22,"mean_commits":"5.2727272727272725","dds":"0.31034482758620685","last_synced_commit":"20bdcefa29c80a0357fb35603aff9c5a431024ee"},"previous_names":["sethvargo/gcr-cleaner"],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoogleCloudPlatform%2Fgcr-cleaner","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoogleCloudPlatform%2Fgcr-cleaner/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoogleCloudPlatform%2Fgcr-cleaner/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoogleCloudPlatform%2Fgcr-cleaner/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GoogleCloudPlatform","download_url":"https://codeload.github.com/GoogleCloudPlatform/gcr-cleaner/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254493378,"owners_count":22080126,"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","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":["artifact-registry","cloud-run","cloud-scheduler","container-registry","google-cloud-run","google-cloud-scheduler","google-container-registry"],"created_at":"2024-09-28T15:10:02.062Z","updated_at":"2025-05-16T08:04:42.420Z","avatar_url":"https://github.com/GoogleCloudPlatform.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GCR Cleaner\n\n\u003e [!CAUTION]\n\u003e\n\u003e The functionality provied by this tool is [now built directly into Artifact Registry](https://cloud.google.com/artifact-registry/docs/repositories/cleanup-policy)! **We are no longer accepting bug reports or feature requests.**\n\nGCR Cleaner deletes old container images in [Docker Hub][docker-hub], [Container Registry][container-registry], [Artifact Registry][artifact-registry], or any Docker v2 registries. This can help reduce storage costs, especially in CI/CD environments where images are created and pushed frequently.\n\nThere are multiple deployment options for GCR Cleaner. Click on your preferred\ndeployment option for a detailed guide:\n\n- [Scheduled GitHub Action workflow](docs/deploy-github-actions.md)\n- [Deployed to Cloud Run](docs/deploy-cloud-run.md)\n- [Deploy to Cloud Build](docs/deploy-cloud-build.md)\n\nFor one-off tasks, you can also run GCR Cleaner locally:\n\n```text\ndocker run -it us-docker.pkg.dev/gcr-cleaner/gcr-cleaner/gcr-cleaner-cli\n```\n\nIf you want gcr-cleaner to inherit the authentication from your local gcloud installation, you must mount the gcloud directory into the container:\n\n```text\ndocker run -v \"${HOME}/.config/gcloud:/.config/gcloud\" -it us-docker.pkg.dev/gcr-cleaner/gcr-cleaner/gcr-cleaner-cli\n```\n\n**This is not an official Google product.**\n\n\n## Container images\n\nPre-built container images are available at the following locations. We do not\noffer versioned container images.\n\n```text\nasia-docker.pkg.dev/gcr-cleaner/gcr-cleaner/gcr-cleaner\neurope-docker.pkg.dev/gcr-cleaner/gcr-cleaner/gcr-cleaner\nus-docker.pkg.dev/gcr-cleaner/gcr-cleaner/gcr-cleaner\n```\n\n\n## Server Payload \u0026amp; parameters\n\n**⚠️ This section is for the _server_ payload. If you are using the CLI tool,\nrun `gcr-cleaner -h` to see the list of flags and their descriptions.**\n\nThe payload is expected to be JSON with the following fields:\n\n- `repos` - List of the full names of the repositories to clean (e.g.\n  `[\"us-docker.pkg.dev/project/my/repo\", \"gcr.io/my/repo\"]`. This field is\n  required.\n\n- `grace` - Relative duration in which to ignore references. This value is\n  specified as a time duration value like \"5s\" or \"3h\". If set, refs newer than\n  the duration will not be deleted. If unspecified, the default is no grace\n  period (all untagged image refs are deleted).\n\n- `keep` - If an integer is provided, it will always keep that minimum number of\n  images. Note that it will not consider images inside the `grace` duration. GCR\n  Cleaner attempts to keep the most recently created images, but there are some\n  caveats. Some community tooling sets container creation time to a date back in\n  1980, which breaks the default sorting algorithm. As such, GCR Cleaner uses\n  the following sorting algorithm for container images:\n\n    - If either of the containers were created before Docker even existed, it\n      sorts by the date the container was uploaded to the registry.\n\n    - If two containers were created at the same timestamp, it sorts by the date\n      the container was uploaded to the registry.\n\n    - In all other situations, it sorts by the timestamp the container was\n      created.\n\n  This algorithm exists to preserve ordering for containers that are moved\n  between registries.\n\n- `tag_filter_any` - If specified, any image with at **least one tag** that\n  matches this given regular expression will be deleted. The image will be\n  deleted even if it has other tags that do not match the given regular\n  expression. The regular expressions are parsed according to the [Go regexp\n  package][go-re].\n\n- `tag_filter_all` - If specified, any image where **all tags** match this given\n  regular expression will be deleted. The image will not be delete if it has\n  other tags that do not match the given regular expression. The regular\n  expressions are parsed according to the [Go regexp package][go-re].\n\n- `dry_run` - If set to true, will not delete anything and outputs what would\n  have been deleted.\n\n- `recursive` - If set to true, will recursively search all child repositories.\n\n    **NOTE!** On Container Registry, you must grant additional permissions to\n    the service account in order to query the registry. The most minimal\n    permissions are `roles/browser`.\n\n    **NOTE!** On Artifact Registry, you must grant additional permissions to the service account in order to query the registry. The most minimal permissions are `roles/storage.objectViewer`.\n\n    **WARNING!** If the authenticated principal has access to many Container\n    Registry or Artifact Registry repos, this will be very slow! This is because\n    the Docker v2 API does not support server-side filtering, meaning GCR\n    Cleaner must download a manifest of all repositories to which you have\n    access and then do client-side filtering. The most granular filter is at the\n    _host_ layer, meaning GCR Cleaner will perform a list operation on `gcr.io`\n    (for Container Registry) or `us-docker.pkg.dev` (for Artifact Registry),\n    parse the response and do client-side filtering to match against the\n    provided patterns, then start deleting. To re-iterate, this operation is\n    **not segmented by project** - if the authenticated principal has access to\n    10,000 repos, the client will need to filter through 10,000 repos. The\n    easiest way to mitigate this is to practice the Principle of Least Privilege\n    and create a dedicated service account that has granular permissions on a\n    subset of repositories.\n\n\n## Permissions\n\nThis section lists the minimum required permissions depending on the target\ncleanup system.\n\n#### Artifact Registry\n\nThe service account running GCR cleaner must have\n`roles/artifactregistry.repoAdmin` or greater on the Artifact Registry\nrepositories. Here is an example for setting that permissions via `gcloud`:\n\n```sh\ngcloud artifacts repositories add-iam-policy-binding \"my-repo\" \\\n  --project \"my-project\" \\\n  --location \"us\" \\\n  --member \"serviceAccount:gcr-cleaner@my-project.iam.gserviceaccount.com\" \\\n  --role \"roles/artifactregistry.repoAdmin\"\n```\n\n#### Container Registry\n\nContainer Registry stores images in Google Cloud Storage, so the service account\nrunning GCR Cleaner must have read and write permissions on the underlying Cloud\nStorage bucket. Here is an example for setting that permission via `gsutil`:\n\n```sh\ngsutil acl ch -u gcr-cleaner@my-project.iam.gserviceaccount.com:W gs://artifacts.my-project.appspot.com\n```\n\nTo clean up Container Registry images hosted in specific regions, update the\nbucket name to include the region:\n\n```text\ngs://eu.artifacts.my-project.appspot.com\n```\n\nIf you plan on using the `recursive` functionality, you must also grant the\nservice account \"Browser\" permissions:\n\n```sh\ngcloud projects add-iam-policy-binding \"my-project\" \\\n  --member \"serviceAccount:gcr-cleaner@my-project.iam.gserviceaccount.com\" \\\n  --role \"roles/browser\"\n```\n\n\n## Debugging\n\nBy default, GCR Cleaner only emits user-level logging at the \"info\" level. More logs are available at the \"debug\" level. To configure the log level, set the `GCRCLEANER_LOG` environment variable to the desired log value:\n\n```sh\nexport GCRCLEANER_LOG=debug\n```\n\nIn debug mode, GCR Cleaner will print **a lot** of information, including its\nentire decision process for candidate deletion. If you open an issue, please\ninclude these debug logs as they are very helpful in finding and fixing any\nbugs.\n\n\n## Concurrency\n\nBy default, GCR Cleaner will attempt to perform operations in parallel. You can\ncustomize the concurrency with `-concurrency` on the CLI or by setting the\nenvironment variable `GCRCLEANER_CONCURRENCY` on the server. It defaults to 20.\n\n\n[artifact-registry]: https://cloud.google.com/artifact-registry\n[container-registry]: https://cloud.google.com/container-registry\n[docker-hub]: https://hub.docker.com\n[go-re]: https://golang.org/pkg/regexp/syntax/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgooglecloudplatform%2Fgcr-cleaner","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgooglecloudplatform%2Fgcr-cleaner","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgooglecloudplatform%2Fgcr-cleaner/lists"}