Trivy EP07 | Fix Docker Image Vulnerabilities Using Trivy | Patch & Push Secure Images to Docker Hub
1. Overview & Problem Statement
When building containerized applications, vulnerabilities are often discovered in Docker images after they have already been built, tested, and pushed to a remote registry like Docker Hub or an enterprise artifact repository. Rather than abandoning these images or rewriting applications from scratch, DevSecOps engineers must know how to inspect, patch, and push secure iterations of existing container images.
In this chapter, we examine how to take an already published image containing known high-severity vulnerabilities, analyze its report via Trivy, author a corrective Dockerfile, rebuild a clean version of the image, verify the patch using local scanning, and finally tag and push the secured image back to Docker Hub.
2. Core Mental Model & Remediation Workflow
Fixing a remote Docker image vulnerability operates on a closed-loop iterative cycle. The fundamental workflow moves from artifact discovery to local container modification, verification, and artifact replacement.
3. Initial Assessment: Scanning Remote Artifacts
When an image is pulled from Docker Hub (for example, a profile summarizer or custom application image), we begin by executing a baseline vulnerability assessment using Trivy.
trivy image <docker-hub-username>/<image-name>:<tag>
Understanding Trivy's Analysis Report
Trivy categorizes findings into two distinct layers:
- OS-Level Vulnerabilities: Flaws in the underlying base image operating system package manager (e.g., Alpine Linux packages like
busybox,libpng,ssl_client). - Package-Manager Level Vulnerabilities: Flaws within runtime dependencies (e.g., npm, pip, maven packages).
When evaluating our demonstration image (an Alpine-based container), Trivy reported 12 total vulnerabilities, including high-severity issues inside core system utilities:
libpng: Found in version1.6.47-R0, with a known fix available in1.6.51-R0(and latest in1.6.53).busybox: Found in version1.37.19, with patches available in1.37.20.ssl_client&zlib: Similar out-of-date system packages with official upstream patches.
4. Naive vs. Production-Ready Patching Approaches
When attempting to patch base images, engineers often make common mistakes regarding package manager syntax or platform architectures.
5. Step-by-Step Evolution: Building the Patch Dockerfile
To resolve the identified high-severity vulnerabilities, we create a Dockerfile that consumes the vulnerable base image, refreshes the Alpine package index, and upgrades the vulnerable packages to their patched versions.
Initial Draft (Containing Common Mistakes)
# Naive / Incorrect Dockerfile
FROM profile-summarizer:v1
RUN apt-get update && apt-get upgrade -y libpng
Note: This fails for two reasons:
- Alpine Linux does not use
apt-get(Debian/Ubuntu-based); it usesapk.- Platform mismatch errors can occur on modern hardware (e.g., Apple Silicon ARM64 vs. AMD64 base images).
Production-Grade Corrected Dockerfile
# Use the vulnerable base image as our starting point
FROM profile-summarizer:v1
# Update the Alpine package index repository
RUN apk update
# Upgrade the specific vulnerable packages to patched versions
RUN apk upgrade libpng busybox ssl_client
6. Resolving Build Pitfalls & Platform Constraints
When executing docker build, you may encounter platform resolution warnings or errors depending on your host machine architecture.
1. Fixing Platform Mismatch Errors
If your host is running ARM64 (such as Apple Silicon M1/M2/M3) and the base image was built for AMD64, Docker will throw an error:
invalid base image platform: expected platform is Linux ARM64
Solution: Explicitly pass the target platform during the build command:
docker build --platform linux/arm64 -t profile-summarizer:fixed-v1 .
2. Fixing Package Manager Errors
If you mistakenly use apt-get on an Alpine container:
/bin/sh: apt-get: not found
Solution: Always match the package manager to the base OS:
- Alpine Linux: Use
apk updateandapk upgrade <package> - Debian / Ubuntu: Use
apt-get updateandapt-get upgrade <package>
7. Complete Verification Flow Walkthrough
Once the corrected image is built locally, we must verify that the vulnerabilities have been successfully neutralized before pushing to production registries.
Step 1: Build the First Iteration (fixed-v1)
docker build --platform linux/arm64 -t myrepo/profile-summarizer:fixed-v1 .
Step 2: Run Trivy Local Scan on fixed-v1
trivy image myrepo/profile-summarizer:fixed-v1
Result: The high-severity vulnerability in libpng is completely gone. However, if other packages (busybox, ssl_client, zlib) remain unpatched, Trivy will still report them.
Step 3: Comprehensive Vulnerability Eradication (fixed-v2)
To achieve zero vulnerabilities, update the Dockerfile to upgrade all flagged packages simultaneously:
FROM profile-summarizer:v1
RUN apk update && apk upgrade libpng busybox ssl_client zlib
Rebuild the image with tag fixed-v2:
docker build --platform linux/arm64 -t myrepo/profile-summarizer:fixed-v2 .
Step 4: Final Trivy Validation Scan
trivy image myrepo/profile-summarizer:fixed-v2
Expected Output Report Summary:
Total: 0 (HIGH: 0, CRITICAL: 0, MEDIUM: 0, LOW: 0)
8. Pushing Secured Images to Docker Hub
With zero vulnerabilities confirmed locally, push the hardened image to your remote artifact registry (Docker Hub).
Local Docker Daemon
|
|---> docker tag myrepo/profile-summarizer:fixed-v2 username/profile-summarizer:v2
|
|---> docker push username/profile-summarizer:v2
v
Docker Hub Artifact Registry (Secure & Patched)
Execution Commands:
# Tag the local image for remote registry push
docker tag myrepo/profile-summarizer:fixed-v2 <your-dockerhub-username>/profile-summarizer:v2
# Push the patched image to Docker Hub
docker push <your-dockerhub-username>/profile-summarizer:v2
Post-Push Verification
- Navigate to your Docker Hub account profile.
- Confirm that the new tag
v2is present and recently updated. - (Optional) Run a final remote scan against the Docker Hub image to ensure integrity post-transit:
BASH
trivy image <your-dockerhub-username>/profile-summarizer:v2
Summary and Key Takeaways
- Proactive vs. Reactive Security: Vulnerabilities can enter artifacts post-push; DevSecOps pipelines must support rapid patching and re-scanning workflows.
- Trivy Report Insights: Trivy isolates vulnerabilities into OS package manager level (e.g., Alpine
apk) and application package dependency level. - Upstream Fix Availability: Trivy reports not only the CVE and severity but also the exact patched target version required to resolve the issue.
- Alpine Package Manager (
apk): When working with Alpine-based base images, always useapk updateandapk upgraderather than Debian-based commands likeapt-get. - Platform Architecture Flags: When building images on cross-architecture hardware (e.g., building AMD64 images on ARM64 Macs), use the
--platformflag duringdocker build. - Iterative Verification: Always run local Trivy scans (
trivy image <tag>) immediately after building a patched Docker image to verify vulnerability reduction before pushing to registries. - Zero-Vulnerability Goal: By systematically upgrading base utilities (
libpng,busybox,ssl_client), engineers can drive high and critical CVE counts down to absolute zero. - Registry Synchronization: Once verified locally, tag and push (
docker push) the hardened image to Docker Hub to ensure production environments pull secure artifacts.