End-of-Life Tracking
Why EOL tracking matters
Section titled “Why EOL tracking matters”Using a runtime past its end-of-life date is a security risk: upstream maintainers stop releasing patches for CVEs. In practice, many teams continue using EOL images because there’s no automatic alert.
imglife integrates EOL tracking into the image lifecycle so you’re warned before EOL, not after.
Data source
Section titled “Data source”imglife fetches EOL data from endoflife.date, a community-maintained database of release cycles for hundreds of products (Alpine Linux, Go, Node.js, Python, Ubuntu, Debian, etc.).
You can also use a local YAML file as the data source — useful for air-gapped environments or custom runtimes not covered by endoflife.date.
EOL alerts in the status report
Section titled “EOL alerts in the status report”When you run imglife status, each image row includes:
| Image | EOL date | Status |
|---|---|---|
| alpine:3.21.3-core1.0.0 | 2026-11-01 | ✅ OK |
| alpine:3.18.6-core1.0.0 | ❌ EOL | ❌ Expired |
| node:20.9.0-core1.0.0 | 2026-04-30 | ⚠️ < 30 days |
The alert threshold is configurable:
export IMGLIFE_ALERT_CRITICAL_DAYS=30 # warn when EOL is within 30 days (default)Configuring the EOL data source
Section titled “Configuring the EOL data source”In your imglife.yaml:
lifecycle: eol_provider: endoflife # default — fetch from endoflife.date eol_target: git # store cache file in git (default) eol_data_file: eol-data.yamlFor air-gapped environments, switch to a local file:
lifecycle: eol_provider: local eol_data_file: eol-data.yamlThe eol-data.yaml file format mirrors endoflife.date’s API response:
alpine: - cycle: "3.21" eol: "2026-11-01" latest: "3.21.3" - cycle: "3.20" eol: "2026-04-01" latest: "3.20.6"golang: - cycle: "1.22" eol: "2026-02-01" latest: "1.22.1"Updating the EOL cache
Section titled “Updating the EOL cache”imglife eol updateThis fetches fresh data from endoflife.date for every product that has a lifecycle: entry in your sync.entries and writes it to eol-data.yaml.
In CI, run this as a scheduled job (e.g. weekly) to keep the cache current. See Base Images — GitLab CI for an example.
Per-image lifecycle configuration
Section titled “Per-image lifecycle configuration”EOL tracking is configured per sync entry:
sync: entries: - source: docker.io/library/alpine tag_regex: '^3\.\d+\.\d+$' target: registry.example.com/mirrors/alpine lifecycle: product: alpine # matches a key in eol-data.yaml / endoflife.date extract: minor # derive cycle from tag: "3.21.3" → "3.21"The extract field tells imglife how to derive the EOL cycle key from the image tag:
| Value | Example tag | Derived cycle |
|---|---|---|
minor | 3.21.3 | 3.21 |
major | 22.04 | 22 |
patch | 1.22.1 | 1.22.1 |
| (none) | lts | lts |
EOL in the check command
Section titled “EOL in the check command”imglife check can also surface EOL data in applicative CI pipelines. When a base image is approaching EOL, the check command:
- With default flags: warns but succeeds
- With
--strict: fails the job if the base is at or past EOL
# In your app's CI pipeline:imglife check --base registry.example.com/bases/alpine:3.18.6-core1.0.0 --strictStorage targets for EOL data
Section titled “Storage targets for EOL data”imglife supports two targets for persisting the EOL cache:
| Target | Description |
|---|---|
git (default) | Writes eol-data.yaml to the local filesystem; commit it to git |
pkgregistry | Uploads the file to the Package Registry (useful when you can’t commit from CI) |
Set the target in lifecycle.eol_target in your config.