How do you keep base images and dependencies free of known vulnerabilities over time?
Quick Answer
This is fundamentally an ongoing process, not a one-time fix: regularly rebuild images from an updated base image (rather than letting a build sit unrebuilt for months, silently accumulating unpatched vulnerabilities in an unchanged image), use automated dependency-update tooling (Dependabot, Renovate) to surface newer, patched versions of both base images and application-level dependencies, and integrate vulnerability scanning (see that question) into both CI and periodic re-scans of already-deployed images, since new vulnerabilities are disclosed continuously in software that hasn't itself changed at all.
Detailed Answer
Why "build it once, ship it forever" is a real security liability
FROM node:20-slim # built 8 months ago, never rebuilt since
Even if an application's own code hasn't changed at all in 8 months, the underlying base image's packages (OS libraries, the language runtime itself) almost certainly have known vulnerabilities disclosed against them by now that weren't known 8 months ago. An image that's never rebuilt slowly accumulates an ever-larger gap between "what's actually running" and "the latest patched versions available," even though nothing about the image's own configuration ever technically changed.
Rebuilding regularly, even without application code changes
# A scheduled CI pipeline (e.g., a nightly or weekly cron-triggered build),
# separate from the normal "build on code push" pipeline, that rebuilds
# the image from the current base image tag and re-scans it
A scheduled rebuild (independent of application code changes) picks up whatever patched packages the base image maintainers have since published under that same tag. This alone closes a meaningful fraction of vulnerabilities over time, purely by re-pulling an updated base layer, with zero application code changes required.
Automated dependency-update tooling
# A Dependabot/Renovate configuration watching for newer available versions
# of base images (in Dockerfiles) and application-level dependencies
# (package.json, requirements.txt, go.mod, etc.), opening pull requests automatically
Tools like Dependabot and Renovate can be configured to watch a project's Dockerfiles and dependency manifests, automatically opening pull requests whenever a newer version becomes available — of a base image tag, or an application-level dependency. This turns "someone has to remember to check for updates" into an automated, continuously-running process that surfaces the work as a reviewable PR rather than requiring anyone to proactively go looking for it.
Continuous scanning, not just at build time
# Periodic re-scan of an ALREADY-DEPLOYED image, on a schedule,
# independent of any new build having happened
trivy image myregistry.example.com/myapp:1.0
As covered in the vulnerability-scanning question, a scan result for an unchanged image can become worse over time purely because new CVEs are disclosed against its existing, unchanged package versions. A scanning strategy that only runs at build or CI time misses this entirely. Genuine ongoing security posture requires periodically re-scanning images that are already deployed and running, not just the ones currently being built.
Prioritizing what to actually fix
CRITICAL: 1 finding
HIGH: 5 findings
MEDIUM: 23 findings
LOW: 47 findings
Not every finding warrants equal urgency. Prioritizing by severity, by whether the vulnerable code path is actually reachable or exploitable in your specific usage, and by whether a fix is even available yet (some CVEs are disclosed before a patched version exists) is a necessary, deliberate triage process. Treating every single low-severity finding as equally urgent as a critical one tends to produce alert fatigue that ultimately causes teams to under-react to the findings that genuinely matter most.
Reducing the surface area to begin with
Smaller base images (Alpine, distroless — see that question) and multi-stage builds (see that question) both directly reduce how much software is present in the final image at all. This correspondingly reduces how much there is to ever have a vulnerability disclosed against in the first place — a genuinely proactive complement to the reactive "scan and patch" cycle described above. Taken together, none of these individual pieces (a scheduled rebuild, an update bot, a scanner) is itself "vulnerability management" — it's the ongoing combination of all of them that is.