Lifecycle Rules¶
Lifecycle rules automatically clean old image tags, keeping storage lean and costs low.
How lifecycle rules work¶
Rules are stored in s3lo.yaml at the bucket root and evaluated by s3lo clean. You can set bucket-wide defaults and per-image overrides.
| Rule | Description |
|---|---|
lifecycle.keep_last |
Keep the N most recently pushed tags. Delete the rest. |
lifecycle.max_age |
Delete tags older than this duration. Supports Nd (e.g. 7d, 90d) and Go duration strings (168h). |
lifecycle.keep_tags |
Named tags that are never deleted regardless of other rules. |
When both keep_last and max_age are set, a tag is deleted if it violates either rule.
Recommended setup¶
Step 1: Set rules¶
# Bucket-wide defaults: keep last 10 tags, max 90 days
s3lo config set s3://my-bucket/ lifecycle.keep_last=10 lifecycle.max_age=90d
# Production images: keep last 5, protect stable/latest
s3lo config set s3://my-bucket/myapp immutable=true lifecycle.keep_last=5 lifecycle.keep_tags=stable,latest
# Dev images: aggressive cleanup, 7 days max
s3lo config set "s3://my-bucket/dev/*" lifecycle.keep_last=3 lifecycle.max_age=7d
Step 2: Dry run¶
Always dry run first to see what would be deleted:
Output:
Tags: 8 would be deleted (out of 23 evaluated)
Blobs: 2 unreferenced (45.20 MB would be freed)
Run with --confirm to apply changes.
Step 3: Apply¶
Step 4: Schedule with GitHub Actions¶
name: Cleanup
on:
schedule:
- cron: '0 2 * * *' # nightly at 2 AM UTC
jobs:
clean:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- uses: OuFinx/s3lo-action@v1
with:
role-to-assume: arn:aws:iam::123456789012:role/ci-s3lo-role
aws-region: us-east-1
- run: s3lo clean s3://my-bucket/ --confirm
Common patterns¶
Good for: images with frequent releases where you want a rolling window.
Good for: dev/staging buckets where old images are never needed.
Good for: production images that have a "stable" pointer tag.
Blob GC¶
clean also runs blob garbage collection by default. After tag pruning, it checks which blobs are still referenced by any remaining tag, and deletes the rest (with a 1-hour grace period for in-progress pushes).
Run blob GC separately if needed:
Viewing the config¶
Use config recommend to get analysis and suggestions based on actual bucket state: