{"id":36975211,"url":"https://github.com/kaskol10/ecr-optimizer","last_synced_at":"2026-01-13T22:03:48.435Z","repository":{"id":327597210,"uuid":"1109942806","full_name":"kaskol10/ecr-optimizer","owner":"kaskol10","description":"Manage AWS ECR container images and reduce storage costs. Delete unused images immediately without lifecycle policy delays.","archived":false,"fork":false,"pushed_at":"2025-12-05T10:29:28.000Z","size":854,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-07T22:53:44.917Z","etag":null,"topics":["aws","container-registry","cost-optimization","devops","docker","ecr","go","helm","image-management","kubernetes","react"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kaskol10.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":".github/SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-04T13:53:47.000Z","updated_at":"2025-12-05T10:29:09.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/kaskol10/ecr-optimizer","commit_stats":null,"previous_names":["kaskol10/ecr-optimizer"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/kaskol10/ecr-optimizer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaskol10%2Fecr-optimizer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaskol10%2Fecr-optimizer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaskol10%2Fecr-optimizer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaskol10%2Fecr-optimizer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kaskol10","download_url":"https://codeload.github.com/kaskol10/ecr-optimizer/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaskol10%2Fecr-optimizer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28399512,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-13T14:36:09.778Z","status":"ssl_error","status_checked_at":"2026-01-13T14:35:19.697Z","response_time":56,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["aws","container-registry","cost-optimization","devops","docker","ecr","go","helm","image-management","kubernetes","react"],"created_at":"2026-01-13T22:03:47.548Z","updated_at":"2026-01-13T22:03:48.429Z","avatar_url":"https://github.com/kaskol10.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ECR Optimizer\n\nA powerful open-source tool to gain visibility into AWS ECR repositories and reduce storage costs by efficiently managing container images. Delete images based on last pull date **without the 90-day waiting period** required by AWS ECR lifecycle policies.\n\n## 🎯 Key Benefits\n\n### vs AWS ECR Lifecycle Policies\n\n- ✅ **No 90-day wait**: Delete images immediately based on last pull date\n- ✅ **No archiving required**: Direct deletion without mandatory archive period\n- ✅ **Full visibility**: See exactly which images will be deleted before confirming\n- ✅ **Immediate cost savings**: Reduce ECR storage costs right away\n- ✅ **Better control**: Delete images on-demand or by date criteria with full transparency\n\n### Features\n\n- **Global View**: Overview of all repositories with total images, size, and top 10 largest repositories\n- **Repository Insights**: View most recently pulled images and largest images per repository\n- **Smart Deletion**: Delete images based on `last_recorded_pulltime` (same field as lifecycle policies)\n- **Batch Operations**: Handle large-scale deletions (supports 1000+ images)\n- **Safety First**: Preview all images before deletion with detailed confirmation modal\n- **SBOM Awareness**: Clear warnings about SBOM deletion before confirming\n\n## 📸 Screenshots\n\n### Global View\nOverview of all repositories with total images, size, and top 20/30 largest/all repositories.\n\n![Global View](docs/images/GlobalView.png)\n\n### Repository View\nDetailed view of a specific repository showing most recently pulled images and largest images.\n\n![Repository View](docs/images/RepositoryView.png)\n\n### Delete Images by Date\nDelete images based on last pull date with date selection.\n\n![Delete Images by Date](docs/images/DeleteImageByDate.png)\n\n### Preview Deletion\nPreview all images that will be deleted before confirming the operation.\n\n![Preview Deletion](docs/images/PreviewDeleteImageByDate.png)\n\n### Confirm Deletion\nFinal confirmation modal with detailed information about images to be deleted, including SBOM warnings.\n\n![Confirm Deletion](docs/images/ConfirmDeletion.png)\n\n## 🚀 Why ECR Optimizer?\n\nAWS ECR lifecycle policies require you to:\n1. Archive images first\n2. Wait up to 90 days before deletion\n3. Have limited visibility into what will be deleted\n\n**ECR Optimizer** gives you:\n- Immediate deletion based on last pull date\n- Full visibility into images before deletion\n- No mandatory waiting periods\n- Significant cost savings by removing unused images immediately\n\n## Tech Stack\n\n- **Backend**: Go with AWS SDK\n- **Frontend**: React with minimalist UI\n- **Architecture**: RESTful API\n\n## Setup\n\n### Prerequisites\n\n- Go 1.21+\n- Node.js 18+\n- AWS credentials configured (via AWS CLI or environment variables)\n- For Kubernetes deployment: Kubernetes 1.19+, Helm 3.0+\n\n### Quick Start\n\nUsing Makefile:\n```bash\nmake install-backend   # Install Go dependencies\nmake install-frontend  # Install Node.js dependencies\nmake run-backend       # Start backend server (port 8081)\nmake run-frontend      # Start frontend dev server (port 3000)\n```\n\nOr manually:\n\n**Backend Setup:**\n```bash\ncd backend\ngo mod download\ngo run main.go\n```\n\nThe backend will run on `http://localhost:8081`\n\n**Frontend Setup:**\n```bash\ncd frontend\nnpm install\nnpm start\n```\n\nThe frontend will run on `http://localhost:3000`\n\n## Kubernetes Deployment\n\n### Using Published Docker Images and Helm Chart\n\nThe project provides pre-built Docker images on GitHub Container Registry and a Helm chart published with each release.\n\n#### Using Published Images\n\nDocker images are automatically built and published to GitHub Container Registry on every push and release:\n\n- **Backend**: `ghcr.io/kaskol10/ecr-optimizer/backend:latest`\n- **Frontend**: `ghcr.io/kaskol10/ecr-optimizer/frontend:latest`\n\nImages are published to `ghcr.io/kaskol10/ecr-optimizer/`.\n\nTo pull images (requires authentication for private repos):\n```bash\n# Login to GitHub Container Registry\necho $GITHUB_TOKEN | docker login ghcr.io -u USERNAME --password-stdin\n\n# Pull images\ndocker pull ghcr.io/kaskol10/ecr-optimizer/backend:latest\ndocker pull ghcr.io/kaskol10/ecr-optimizer/frontend:latest\n```\n\n#### Using Published Helm Chart\n\nInstall from GitHub Releases:\n\n```bash\n# Download the Helm chart from the latest release\nhelm install ecr-optimizer https://github.com/kaskol10/ecr-optimizer/releases/download/v0.1.0/ecr-optimizer-0.1.0.tgz \\\n  --set image.backend.repository=ghcr.io/kaskol10/ecr-optimizer/backend \\\n  --set image.frontend.repository=ghcr.io/kaskol10/ecr-optimizer/frontend \\\n  --set aws.region=us-east-1 \\\n  --set aws.credentialsSecret=aws-credentials\n```\n\nOr use IAM Role for Service Account (recommended for EKS):\n```bash\nhelm install ecr-optimizer https://github.com/kaskol10/ecr-optimizer/releases/download/v0.1.0/ecr-optimizer-0.1.0.tgz \\\n  --set image.backend.repository=ghcr.io/kaskol10/ecr-optimizer/backend \\\n  --set image.frontend.repository=ghcr.io/kaskol10/ecr-optimizer/frontend \\\n  --set aws.useIRSA=true \\\n  --set aws.roleArn=arn:aws:iam::ACCOUNT_ID:role/ecr-optimizer-role\n```\n\n**Note**: Make sure to replace `kaskol10` with your actual GitHub username/organization and update the version number in the URL.\n\n### Using Local Helm Chart\n\nThe project includes a Helm chart for easy Kubernetes deployment with support for both sidecar and separate deployment patterns.\n\n#### Quick Start\n\n```bash\n# Build Docker images locally\nmake docker-all\n\n# Install with default values (sidecar pattern)\nhelm install ecr-optimizer ./helm/ecr-optimizer \\\n  --set aws.region=us-east-1 \\\n  --set aws.credentialsSecret=aws-credentials\n\n# Or use IAM Role for Service Account (recommended for EKS)\nhelm install ecr-optimizer ./helm/ecr-optimizer \\\n  --set aws.useIRSA=true \\\n  --set aws.roleArn=arn:aws:iam::ACCOUNT_ID:role/ecr-optimizer-role\n```\n\n#### Deployment Patterns\n\n**Sidecar Pattern (default):**\n- Backend and frontend run in the same pod\n- Frontend nginx proxies API calls to localhost backend\n- More efficient resource usage\n\n**Separate Pattern:**\n- Backend and frontend run in separate deployments\n- Better for scaling independently\n- Set `deploymentPattern: \"separate\"` in values.yaml\n\n#### Configuration\n\nSee `helm/ecr-optimizer/values.yaml` for all configuration options.\n\nKey settings:\n- `aws.region`: AWS region for ECR access\n- `aws.useIRSA`: Use IAM Role for Service Account (recommended for EKS)\n- `aws.credentialsSecret`: Kubernetes secret name containing AWS credentials\n- `deploymentPattern`: \"sidecar\" or \"separate\"\n- `ingress.enabled`: Enable ingress for external access\n\nFor detailed Helm documentation, see [helm/README.md](helm/README.md).\n\n## Configuration\n\nThe backend uses AWS credentials from:\n- Environment variables (`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_REGION`)\n- AWS credentials file (`~/.aws/credentials`)\n- IAM role (if running on EC2)\n\n## Usage\n\n1. Start the backend server (`make run-backend` or `cd backend \u0026\u0026 go run main.go`)\n2. Start the frontend development server (`make run-frontend` or `cd frontend \u0026\u0026 npm start`)\n3. Navigate to `http://localhost:3000`\n4. Select a repository from the sidebar\n5. View dashboard, most downloaded images, or largest images\n6. Delete images individually or by date criteria\n\n## Important Notes\n\n### Pull Count Tracking\nAWS ECR does not provide per-image pull count metrics. The application uses heuristics based on image scan dates and age. For accurate pull tracking, consider implementing CloudWatch Logs Insights queries or custom analytics.\n\n### Last Pull Date\nThe app uses ECR's `last_recorded_pulltime` field (same as lifecycle policies use) for accurate pull date tracking. If an image was never pulled, it falls back to the pushed date. See `backend/NOTES.md` for more details.\n\n### Image Deletion\nThe delete-by-date feature uses ECR's `last_recorded_pulltime` field (same as lifecycle policies) for accurate deletion based on actual pull times. Always verify images before bulk deletion using the preview feature.\n\n## API Endpoints\n\n- `GET /api/repositories` - List all ECR repositories\n- `GET /api/global-stats` - Get aggregate statistics across all repositories (total repos, total images, total size)\n- `GET /api/images?repository=\u003cname\u003e` - Get all images in a repository\n- `GET /api/images/most-downloaded?repository=\u003cname\u003e\u0026limit=10` - Get most recently pulled images\n- `GET /api/images/largest?repository=\u003cname\u003e\u0026limit=10` - Get largest images\n- `POST /api/images/delete` - Delete specific images by digest\n- `POST /api/images/delete-by-date` - Delete images older than X days since last pull\n\n## Releases\n\nReleases are automatically created when you push a version tag (e.g., `v1.0.0`). The release process:\n\n1. **Builds and publishes Docker images** to GitHub Container Registry\n2. **Packages and publishes the Helm chart** to GitHub Releases\n3. **Creates a GitHub Release** with release notes\n\nTo create a release:\n\n```bash\n# Tag a new version\ngit tag -a v1.0.0 -m \"Release version 1.0.0\"\ngit push origin v1.0.0\n```\n\nThe GitHub Actions workflows will automatically:\n- Build and push Docker images with tags: `v1.0.0`, `1.0.0`, `1.0`, `1`, and `latest`\n- Package the Helm chart and attach it to the release\n- Create release notes\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n### Development Setup\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\n3. Make your changes\n4. Commit your changes (`git commit -m 'Add some amazing feature'`)\n5. Push to the branch (`git push origin feature/amazing-feature`)\n6. Open a Pull Request\n\n### Building and Testing\n\n```bash\n# Run tests\nmake install-backend\nmake install-frontend\n\n# Build locally\nmake build-all\n\n# Build Docker images\nmake docker-all\n```\n\n## Use Cases\n\n- **Cost Optimization**: Reduce AWS ECR storage costs by removing unused images immediately\n- **Compliance**: Clean up old images without waiting for lifecycle policy delays\n- **Visibility**: Get insights into which images are actually being used\n- **Automation**: Integrate into CI/CD pipelines for automated cleanup\n\n## License\n\nApache License 2.0 - see [LICENSE](LICENSE) file for details.\n\n## Disclaimer\n\nThis tool performs irreversible deletions. Always review images carefully before deletion. The authors are not responsible for any data loss. Use at your own risk.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkaskol10%2Fecr-optimizer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkaskol10%2Fecr-optimizer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkaskol10%2Fecr-optimizer/lists"}