"How to Scan Docker Images for Vulnerabilities in 3 Commands (2026)"
How to scan Docker images for vulnerabilities in under a minute. One command covers base OS, system libraries, and app dependencies. Includes Dockerfile fixes, CI/CD scanning, and 5 best practices.
Quick Answer: How to Scan a Docker Image for Vulnerabilities
Scan any Docker image in one command with an open-source scanner:
pip install vulnledger
vulnledger scan docker://nginx:latest
That's it — VulnLedger pulls the image, checks every package (base OS, system libraries, and app dependencies) against OSV.dev, and prints a severity-ranked vulnerability report. For CI/CD, add the --ci flag to fail the build on critical or high CVEs:
vulnledger scan docker://nginx:latest --ci
Alternatives: Trivy (trivy image nginx:latest) and Grype (grype nginx:latest) are the other popular free Docker image scanners — see the comparison below.
Container images are one of the biggest attack surfaces in modern software. A single vulnerable package in your Docker image can compromise your entire application.
This guide covers how to scan containers, what to look for, and how to integrate scanning into your workflow.
Why Container Scanning Matters
- 60% of container images contain at least one critical vulnerability
- Base images often have hundreds of outdated packages
- Supply chain attacks increasingly target container registries
- Compliance frameworks now require container SBOMs
The statistics are sobering:
- Average container has 150+ packages
- 10-20% of those packages have known CVEs
- Mean time to patch: 120+ days (without automation)
- Mean time to exploit: hours after CVE disclosure
Docker Image Scanner Comparison
| Tool | Command | Free? | Web dashboard | SBOM export | Best for |
|---|---|---|---|---|---|
| VulnLedger | vulnledger scan docker://img | Yes | Yes (cloud) | CycloneDX/SPDX | Teams needing dashboard + compliance |
| Trivy | trivy image img | Yes | No | Yes | CLI-only scanning |
| Grype | grype img | Yes | No | Yes (SPDX) | Anchore ecosystem users |
| Snyk | snyk container test img | Paid | Yes | Yes | Enterprise security teams |
| Docker Scout | docker scout cves img | Free tier | Yes | No | Docker Desktop users |
All five catch the same critical CVEs — the differences are speed, depth, and whether you get a dashboard, SBOM, and compliance reports afterward.
How Container Scanning Works
Containers have multiple layers, each with its own dependencies:
Container Layer Stack:
- Layer 1 — Application Code: Your custom code (app.py, main.js, etc.)
- Layer 2 — Language Packages: pip/npm/cargo dependencies (requirements.txt, package.json)
- Layer 3 — System Libraries: apt/yum packages installed in the image
- Layer 4 — Base OS Image: Ubuntu, Alpine, Debian, Distroless
Each layer can have different vulnerabilities. A complete scan covers all layers.
Method 1: Scan a Docker Image
With VulnLedger CLI:
vulnledger scan docker://nginx:latest
This scans the image and checks every package against OSV.dev.
For specific images:
# Official images
vulnledger scan docker://python:3.11-slim
vulnledger scan docker://node:20-alpine
vulnledger scan docker://redis:7
# Custom images
vulnledger scan docker://myregistry.io/myapp:v1.2.3
# Local images
docker build -t myapp .
vulnledger scan docker://myapp:latest
Method 2: Scan During Build (CI/CD)
Add scanning to your GitHub Actions workflow:
name: Container Security
on: [push, pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build image
run: docker build -t myapp:${{ github.sha }} .
- name: Scan image
run: |
pip install vulnledger
vulnledger scan docker://myapp:${{ github.sha }} --ci
- name: Generate SBOM
run: |
vulnledger scan docker://myapp:${{ github.sha }} --json --output sbom.json
The --ci flag makes this a security gate — the build fails if critical/high vulnerabilities are found.
Method 3: Web Dashboard
VulnLedger Cloud lets you scan container images directly from the web UI:
1. Go to vulnledger.com/dashboard
2. Click "Scan Container Image"
3. Enter image reference (e.g., nginx:latest)
4. Get results in seconds
Understanding Container Vulnerabilities
Base Image Vulnerabilities
The most common source of container vulnerabilities is the base image. For example:
FROM ubuntu:20.04
# Ubuntu 20.04 has 200+ known CVEs
# Even with latest patches, some remain
Solution: Use minimal base images:
FROM python:3.11-slim # Better than python:3.11
FROM alpine:3.19 # Even smaller
FROM gcr.io/distroless/python3 # Smallest possible
Application Layer Vulnerabilities
Your application's dependencies (pip, npm, cargo) are the second source:
FROM python:3.11-slim
COPY requirements.txt .
RUN pip install -r requirements.txt # <- This is where vulns come from
COPY . .
Solution: Scan after pip install:
vulnledger scan . --ci # Scan Python dependencies
Transitive Dependencies
A single pip install flask pulls in 15+ packages. A vulnerability in any of them affects your image.
Solution: Use SBOMs to track the full dependency tree:
vulnledger scan docker://myapp:latest --json --output sbom.json
Best Practices
1. Scan Before Deploying
Never push unscanned images to production:
# In your CI pipeline
- name: Scan before push
run: |
vulnledger scan docker://myapp:${{ github.sha }} --ci
# Only proceeds if scan passes
2. Use Minimal Base Images
| Image | Size | CVEs | Recommendation |
|---|---|---|---|
| ubuntu:22.04 | 77MB | 200+ | Avoid for containers |
| python:3.11 | 900MB | 150+ | Use slim variant |
| python:3.11-slim | 130MB | 50+ | Better |
| python:3.11-alpine | 50MB | 20+ | Best for Python |
| gcr.io/distroless/python3 | 25MB | 10+ | Best overall |
3. Pin Versions
# Bad - pulls latest, may break
FROM python:latest
# Good - specific version
FROM python:3.11.9-slim
# Best - digest pinning
FROM python@sha256:abc123...
4. Multi-Stage Builds
# Build stage
FROM python:3.11-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
# Runtime stage (smaller, fewer CVEs)
FROM python:3.11-slim
COPY --from=builder /app /app
CMD ["python", "app.py"]
5. Automate Monitoring
# Daily scan via cron
- name: Daily container scan
run: |
vulnledger scan docker://myapp:latest --json --output daily-scan.json
Remediation
When vulnerabilities are found:
1. Check for fixes — Most CVEs have patched versions
2. Update base images — Pull the latest version
3. Remove unused packages — Fewer packages = smaller attack surface
4. Use VEX documents — Document accepted risks for unfixable vulnerabilities
5. Test thoroughly — Upgrades can break things
Priority Matrix
| Severity | SLA | Action |
|---|---|---|
| Critical | 24 hours | Fix immediately or mitigate |
| High | 7 days | Plan fix in next sprint |
| Medium | 30 days | Track and fix in regular releases |
| Low | 90 days | Document and monitor |
FAQ
Q: What is the best tool to scan Docker images for vulnerabilities?
A: The most popular free Docker image scanners are VulnLedger (vulnledger scan docker://img), Trivy (trivy image img), and Grype (grype img). All three catch critical CVEs. VulnLedger adds a web dashboard and SBOM export for compliance; Docker Scout is also free if you already use Docker Desktop.
Q: How do I scan a Docker image in CI/CD?
A: Add a scanning step to your pipeline that runs after the image is built. With GitHub Actions: vulnledger scan docker://img --ci fails the build on critical/high CVEs. See the CI/CD section above for full YAML.
Q: Is docker scan a real Docker command?
A: No. docker scan was a plugin that Docker removed in 2024 — running it now returns "not a docker command". The free modern alternatives are VulnLedger, Trivy, Grype, and Docker Scout.
Q: How long does a Docker image scan take?
A: 30-90 seconds for typical images. Vulnerable package databases are indexed by file hash, so most checks are instant — only download and SBOM extraction take time.
Q: What's the difference between scanning the base image and the app dependencies?
A: The base OS packages (Alpine's apk, Ubuntu's apt) are checked separately from your application dependencies (npm, pip, Go modules). Tools like VulnLedger and Trivy check both in one pass; pip-audit alone only sees Python dependencies.
Conclusion
Container scanning is essential for modern DevOps. Make it part of your CI/CD pipeline and you'll catch vulnerabilities before they reach production.
Get started:
pip install vulnledger
vulnledger scan docker://your-image:latest