The Layers of a Container Image
When you package your application into a Docker container, you are not just shipping your code. You are shipping a complete, self-contained mini operating system. A typical container image consists of:
- Base OS layer — e.g.,
ubuntu:22.04oralpine:3.18. This includes the OS userspace, package manager, and core utilities. - System package layers — Packages installed via
apt,apk, oryum(e.g.,curl,openssl,libssl). - Language runtime layer — e.g., Python 3.11, Node.js 20, OpenJDK 17.
- Application layer — Your actual code and its dependencies.
Vulnerabilities can exist in any of these layers. A perfectly written application running on an ubuntu:20.04 base image with an unpatched openssl is still vulnerable to OpenSSL CVEs. Container scanners exist specifically to audit these OS-level and runtime-level components.
How Container Scanners Work
Tools like Trivy (by Aqua Security, open-source) and Grype (by Anchore, open-source) work by:
- Pulling the container image and unpacking its layers.
- Inventorying all installed OS packages (from the package manager database, e.g.,
/var/lib/dpkg/statusfor Debian-based images). - Inventorying language-level packages (pip, npm, gem, etc.) found in the filesystem.
- Cross-referencing all findings against vulnerability databases (NVD, Alpine SecDB, Debian Security Tracker, etc.).
- Producing a report sorted by severity (Critical, High, Medium, Low).
Trivy is the most widely adopted open-source container scanner. A basic scan is a single command naming the image to check — running it against nginx:1.25.0, for instance, outputs a table of all CVEs found in that image, including the package name, installed version, fixed version, and severity.
When it runs: Immediately after the container image is built in CI (before it is pushed to the registry). Many teams also configure their container registry (e.g., AWS ECR, Google Artifact Registry, Harbor) to continuously re-scan stored images as new CVEs are published — an image that was clean last month may be vulnerable today.
Practical tip — use minimal base images: The single most effective way to reduce container vulnerability surface area is to use minimal base images. alpine has ~10 packages; ubuntu has ~400. Fewer packages means fewer potential CVEs. distroless images (from Google) contain only the application and its runtime, with no shell or package manager at all — dramatically reducing attack surface.
Key Point: Container scanning and SCA are complementary. SCA covers your application-level dependencies (requirements.txt, package.json). Container scanning covers the OS and system-level packages in the image. A complete posture requires both. Trivy is notable because it performs both in a single scan, making it a popular choice for teams that want one tool to cover both layers.