registry-cleanup
Automates cleanup of old container images from DigitalOcean registries based on retention policies. Keeps last 10 tags for staging, 30 for production, always preserves :latest.
Packaged view
This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.
Install command
npx @skill-hub/cli install darkmonkdev-witchcityrope-registry-cleanup
Repository
Skill path: .claude/skills/registry-cleanup
Automates cleanup of old container images from DigitalOcean registries based on retention policies. Keeps last 10 tags for staging, 30 for production, always preserves :latest.
Open repositoryBest for
Primary workflow: Ship Full Stack.
Technical facets: Full Stack.
Target audience: everyone.
License: Unknown.
Original source
Catalog source: SkillHub Club.
Repository owner: DarkMonkDev.
This is still a mirrored public skill entry. Review the repository before installing into production workflows.
What it helps with
- Install registry-cleanup into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
- Review https://github.com/DarkMonkDev/WitchCityRope before adding registry-cleanup to shared team environments
- Use registry-cleanup for development workflows
Works across
Favorites: 0.
Sub-skills: 0.
Aggregator: No.
Original source / Raw SKILL.md
---
name: registry-cleanup
description: Automates cleanup of old container images from DigitalOcean registries based on retention policies. Keeps last 10 tags for staging, 30 for production, always preserves :latest.
---
# Registry Cleanup Skill
**Purpose**: Clean up old container images to manage storage costs in DigitalOcean Container Registries.
**When to Use**:
- Weekly maintenance (recommended)
- When storage usage is high
- After major deployment cycles
- Before month-end to reduce storage costs
**When NOT to Use**:
- During active deployments (wait for deployment to complete)
- If unsure about which tags are safe to delete (use dry-run mode first)
- Without reviewing dry-run output first
---
## π¨ SINGLE SOURCE OF TRUTH
**This skill is the ONLY registry cleanup procedure.**
**DO NOT duplicate registry cleanup automation in:**
- β Agent definitions
- β Lessons learned (reference this skill instead)
- β Process documentation
- β Deployment guides
---
## Retention Policies
### WitchCityRope Registry
| Repository | Retention | Always Keep | Purpose |
|------------|-----------|-------------|---------|
| `witchcityrope-api-staging` | **10 tags** | `:latest` | Staging API images |
| `witchcityrope-web-staging` | **10 tags** | `:latest` | Staging Web images |
| `witchcityrope-api-production` | **30 tags** | `:latest` | Production API images |
| `witchcityrope-web-production` | **30 tags** | `:latest` | Production Web images |
### Accounting Registry
| Repository | Retention | Always Keep | Purpose |
|------------|-----------|-------------|---------|
| `accounting-api` | **30 tags** | `:latest` | Production API (treat as production) |
| `accounting-web` | **30 tags** | `:latest` | Production Web (treat as production) |
**Rationale**:
- **Staging (10 tags)**: Fast iteration, lower rollback depth needed
- **Production (30 tags)**: Longer rollback window, compliance, audit trail
- **:latest tag**: Always preserved for consistent deployments
---
## How to Use This Skill
**Executable Script**: `execute.sh`
### Dry-Run Mode (Default - Recommended First)
```bash
# From project root - shows what WOULD be deleted
bash .claude/skills/registry-cleanup/execute.sh
```
**Output**: Shows repositories, tag counts, tags that would be deleted, estimated storage savings.
**NO CHANGES MADE** - Safe to run anytime.
### Confirm Mode (Actually Delete)
```bash
# From project root - ACTUALLY DELETES old tags
bash .claude/skills/registry-cleanup/execute.sh --confirm
```
**Output**: Shows repositories, deletes old tags, reports actual deletions, storage freed.
**DESTRUCTIVE** - Tags deleted cannot be recovered.
### What the Script Does
1. **Retrieves DigitalOcean API token** from .NET User Secrets
2. **Validates prerequisites**:
- API token accessible
- `curl` and `jq` installed
- Registry access working
3. **For each repository**:
- Lists all tags via DigitalOcean API
- Sorts by creation date (newest first)
- Identifies tags beyond retention limit
- Skips `:latest` tag (always preserved)
- Shows/deletes old tags based on mode
4. **Reports summary**:
- Total tags processed
- Tags deleted (or would be deleted)
- Estimated storage freed
---
## Safety Features
### Built-In Protections
- β
**Dry-run by default** - No deletions unless `--confirm` flag used
- β
**:latest tag protected** - Never deleted, even if old
- β
**Sorted by date** - Keeps newest tags, deletes oldest
- β
**Detailed logging** - Shows exactly what will be deleted
- β
**Error handling** - Stops on API errors, doesn't continue blindly
- β
**Audit trail** - Logs all deletions to stdout (redirect to file for records)
### Recommended Workflow
1. **Run dry-run first**: `bash execute.sh`
2. **Review output carefully**: Check tags to be deleted
3. **Verify no active deployments**: Wait for deploys to finish
4. **Run with confirmation**: `bash execute.sh --confirm`
5. **Save audit log**: Redirect output to file for compliance
```bash
# Example: Save audit log
bash .claude/skills/registry-cleanup/execute.sh --confirm 2>&1 | tee registry-cleanup-$(date +%Y-%m-%d).log
```
---
## Example Output
### Dry-Run Mode
```
π§Ή Registry Cleanup - DRY RUN MODE
===================================
π Analyzing WitchCityRope Registry
-----------------------------------
Repository: witchcityrope-api-staging
Total tags: 25
Retention policy: 10 most recent
Tags to delete: 15
Keeping (10 newest + :latest):
β
sha-abc123f (2025-11-22)
β
sha-def456g (2025-11-21)
... (8 more)
β
latest (protected)
Would delete (15 oldest):
ποΈ sha-xyz789h (2025-10-15)
ποΈ sha-uvw456i (2025-10-10)
... (13 more)
Estimated storage freed: ~350 MB
Repository: witchcityrope-web-staging
Total tags: 18
Retention policy: 10 most recent
Tags to delete: 8
Would delete (8 oldest):
ποΈ sha-rst234j (2025-10-18)
... (7 more)
Estimated storage freed: ~200 MB
π Summary
----------
Total repositories: 6
Total tags: 125
Tags to keep: 72
Tags to delete: 53
Estimated storage freed: ~850 MB
β οΈ DRY RUN - No changes made
βΉοΈ Run with --confirm to actually delete tags
```
### Confirm Mode
```
π§Ή Registry Cleanup - CONFIRM MODE
===================================
β οΈ WARNING: This will DELETE old tags permanently!
... (same analysis as dry-run) ...
ποΈ Deleting tags from witchcityrope-api-staging...
Deleted: sha-xyz789h β
Deleted: sha-uvw456i β
... (13 more)
β
Deleted 15 tags from witchcityrope-api-staging
... (repeat for other repositories) ...
π Summary
----------
Total repositories: 6
Total tags deleted: 53
Actual storage freed: ~850 MB
β
Registry cleanup complete
```
---
## Integration Points
### With Deployment Skills
- **staging-deploy** skill pushes new images with `:latest` and `:sha-XXXXXX` tags
- **production-deploy** skill pushes new images with `:latest` and `:sha-XXXXXX` tags
- This skill cleans up old SHA tags while preserving `:latest`
### With Weekly Maintenance
Recommended cron schedule:
```bash
# Every Sunday at 2 AM
0 2 * * 0 cd /home/chad/repos/witchcityrope && bash .claude/skills/registry-cleanup/execute.sh --confirm 2>&1 | tee -a /var/log/registry-cleanup.log
```
### With Cost Management
Monitor storage costs in DigitalOcean dashboard:
- Container Registry β Storage Usage
- Compare before/after cleanup
- Adjust retention policies if needed
---
## Troubleshooting
### Common Issues
#### API Token Not Found
**Error**: `User secrets not found or empty`
**Solution**:
```bash
cd /home/chad/repos/witchcityrope/apps/api
dotnet user-secrets list | grep DigitalOcean:Token
```
If empty, set token:
```bash
dotnet user-secrets set "DigitalOcean:Token" "YOUR_TOKEN_HERE"
```
#### Registry Access Denied
**Error**: `401 Unauthorized`
**Solution**: Token may be expired or invalid. Generate new token:
1. Go to https://cloud.digitalocean.com/account/api/tokens
2. Generate new Personal Access Token (read/write scopes)
3. Update user secrets with new token
#### Tag Deletion Fails
**Error**: `404 Not Found` or `500 Server Error`
**Solution**:
- Tag may already be deleted (concurrent deletion)
- Tag may be in use (active deployment)
- Wait 5 minutes, retry
- Check DigitalOcean status page for API issues
#### Storage Not Freed
**Symptom**: Tags deleted but storage usage unchanged
**Explanation**: DigitalOcean processes deletions asynchronously. Wait 1-2 hours for storage metrics to update.
---
## Configuration
### Adjusting Retention Policies
Edit `execute.sh` to modify retention counts:
```bash
# Repository configurations (line ~80)
declare -A RETENTION
RETENTION["witchcityrope-api-staging"]=10 # Change to 5, 15, etc.
RETENTION["witchcityrope-web-staging"]=10
RETENTION["witchcityrope-api-production"]=30 # Change to 20, 50, etc.
RETENTION["witchcityrope-web-production"]=30
```
**Consider**:
- **Lower retention** = More storage savings, shorter rollback window
- **Higher retention** = More storage costs, longer rollback window
- **Compliance requirements**: Some industries require longer retention
### Adding New Repositories
Edit `execute.sh` to add new repositories:
```bash
# Repository configurations (line ~80)
RETENTION["new-service-staging"]=10
RETENTION["new-service-production"]=30
```
Skill automatically processes all configured repositories.
---
## API Documentation
### DigitalOcean Container Registry API
**List Repository Tags**:
```bash
curl -X GET \
-H "Authorization: Bearer $TOKEN" \
"https://api.digitalocean.com/v2/registry/witchcityrope/repositories/witchcityrope-api-staging/tags"
```
**Delete Tag**:
```bash
curl -X DELETE \
-H "Authorization: Bearer $TOKEN" \
"https://api.digitalocean.com/v2/registry/witchcityrope/repositories/witchcityrope-api-staging/tags/sha-abc123f"
```
**Response Codes**:
- `200 OK` - List successful
- `204 No Content` - Delete successful
- `401 Unauthorized` - Invalid token
- `404 Not Found` - Repository/tag not found
- `429 Too Many Requests` - Rate limited (wait 60 seconds)
---
## Version History
- **2025-11-22**: Initial creation
- Support for 6 repositories (WitchCityRope + Accounting)
- Dry-run and confirm modes
- Retention policies (10 staging, 30 production)
- :latest tag protection
- Audit logging support
---
**For questions or issues**: Consult DigitalOcean Container Registry documentation or raise issue in repository.