trivy: Cache the Vulnerability DB in CI
Caching the Trivy vulnerability database across CI runs avoids re-downloading it every job and prevents registry rate limits.
Trivy downloads its vulnerability database from a container registry on first use. In CI that download repeats every job, wasting time and tripping rate limits. Caching the DB directory fixes both.
What it does
Trivy stores its databases under a cache directory (by default ~/.cache/trivy, overridable with --cache-dir or TRIVY_CACHE_DIR). Persisting that directory between runs lets Trivy reuse the DB. --skip-db-update and --skip-java-db-update tell Trivy to use the cached copy without contacting the registry.
Common usage
export TRIVY_CACHE_DIR=.trivycache
# pre-warm the DB once (and cache the directory in CI)
trivy image --download-db-only
# scan reusing the cache, skipping the update call
trivy image --skip-db-update --severity HIGH,CRITICAL myorg/app:ciOptions
| Flag | What it does |
|---|---|
| --cache-dir <dir> | Where Trivy stores databases and fanal cache |
| --download-db-only | Fetch the vulnerability DB and exit |
| --skip-db-update | Use the cached DB without checking for updates |
| --skip-java-db-update | Same for the Java index DB |
| --db-repository <ref> | Pull the DB from a mirror registry |
In CI
Cache TRIVY_CACHE_DIR (or ~/.cache/trivy) with your CI cache key, run trivy image --download-db-only once to warm it, then scan with --skip-db-update. If you hit GHCR rate limits, mirror the DB to your own registry and point --db-repository at it.
Common errors in CI
"TOOMANYREQUESTS: retry-after" when downloading the DB means the public registry rate-limited an unauthenticated runner; cache the DB or authenticate. "the local DB is outdated" with --skip-db-update means the cached DB is too old to use; drop the skip flag once to refresh it. A cache that never speeds things up usually has the wrong directory cached.