Container Vulnerability Scanning Tools: Trivy vs Grype vs Snyk vs Docker Scout
A practitioner's comparison of Trivy, Grype, and Snyk for finding CVEs in container images, plus how to wire scanning into CI without drowning in noise.
Key takeaways
- The main container vulnerability scanning tools are Trivy and Grype (free, open source), Snyk Container (commercial, best fix advice), and Docker Scout (built into Docker).
- For most teams, run Trivy in CI and fail on fixable HIGH and CRITICAL CVEs, use minimal base images, keep registry scanning on as a backstop, and pin scanner actions to commit SHAs.
On this page
The container vulnerability scanners worth knowing are Trivy and Grype (free, open source), Snyk Container (commercial, strongest fix advice), Docker Scout (built into Docker Desktop and Hub), and your registry's built-in scanner. Our default: Trivy in CI, failing on fixable HIGH and CRITICAL CVEs, with registry scanning as a backstop.
An image that scanned clean in March is full of new findings by July, not because anything changed, but because the world learned more about what was already there. Scanning is a continuous job.
Why images pile up CVEs
Three sources feed the pile:
Base image: start from ubuntu:22.04 or node:20 and you inherit hundreds of packages you never chose.
OS packages: shared libraries like openssl, glibc, zlib, and curl get CVEs disclosed against them constantly, whether or not your Dockerfile touches them.
Application dependencies: the npm, pip, go, and Maven packages your code imports, plus transitive ones. This overlaps with dependency and SCA scanning, and good container scanners cover it too.
What scanners actually check
A full scan covers:
- OS packages: cross-reference installed package versions against vulnerability databases (NVD, distro security trackers, GitHub Advisories).
- Language dependencies: parse lockfiles and installed modules for known-vulnerable versions.
- Misconfiguration: Dockerfile and IaC checks (running as root, no
USERdirective, world-writable files). - Secrets: hardcoded API keys, tokens, and private keys baked into a layer.
- Licenses: flag GPL or other licenses that violate your policy.
Not every tool does all five, and that spread is most of the difference between them.
The tools compared
| Tool | License / price (Oct 2026) | Latest release | Scans | Best for |
|---|---|---|---|---|
| Trivy (Aqua) | Open source, free | v0.75.0 | OS, language deps, IaC, secrets, licenses | One free scanner for everything |
| Grype + Syft (Anchore) | Open source, free | Grype v0.120.1, Syft v1.54.1 | OS and language deps, from SBOMs | SBOM-first pipelines |
| Snyk Container | Free tier; Team from $25/month | SaaS | OS and app deps, base-image advice | Guided fixes, IDE and PR integration |
| Docker Scout | Free on 1 repo (Personal); unlimited from Team at $15/user/month annual | Built into Docker | OS and app deps, policies | Teams already on Docker Hub |
| Registry scanning (ECR, Artifact Registry, ACR) | Billed by cloud provider | Managed | OS and app deps on push | A backstop that runs regardless of CI |
Trivy (Aqua Security)
Open source, fast, and broad: one binary, no server, the widest coverage for free. A basic scan:
$ trivy image myapp:1.4.2
myapp:1.4.2 (debian 12.4)
Total: 14 (HIGH: 11, CRITICAL: 3)
Library Vulnerability Severity Status Installed Fixed
libssl3 CVE-2024-6119 HIGH fixed 3.0.11-1 3.0.13-1~deb12u1
zlib1g CVE-2023-45853 CRITICAL affected 1:1.2.13-1
fixed means an upgrade exists; affected means no patched version has shipped yet. That distinction drives triage.
Grype (Anchore)
Open source and built around SBOMs: Syft produces the bill of materials once, Grype rescans it as new CVEs land, without re-pulling the image. If you already generate SBOMs for supply-chain security, it fits naturally. It does less than Trivy on misconfig and secrets.
Snyk
Commercial and developer-focused. Snyk's edge is fix advice: the exact base-image bump that clears the most CVEs, surfaced in IDEs and PRs, plus curated vulnerability data. For teams that want guided remediation rather than raw findings, it earns its price.
The rest
Docker Scout: built into Docker Desktop and Hub, with decent base-image recommendations. The free Personal plan covers one Scout-enabled repository.
Clair: the older open-source engine behind Quay; heavier to operate standalone.
Registry-native scanning: ECR, Artifact Registry, and ACR scan on push. A safety net, not a substitute for checking in the build.
The workflow that actually works
Fail the build on HIGH/CRITICAL. Here is a GitHub Actions step using Trivy, pinned to a commit SHA. In March 2026 attackers force-pushed malicious code over almost every version tag of aquasecurity/trivy-action, and Aqua's advisory names full-SHA pinning as the only reliable protection:
- name: Scan image for vulnerabilities
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
with:
image-ref: myapp:${{ github.sha }}
format: table
exit-code: '1' # fail the job on a match
severity: HIGH,CRITICAL
ignore-unfixed: true # only block on CVEs that have a fix
ignore-unfixed: true is the pragmatic setting: blocking on a CRITICAL with no patch stops your pipeline over something you cannot act on.
Scan and pin the base image. Pin by digest, not a floating tag, and rebuild on a schedule so base-image patches actually reach production.
Shrink the surface. Distroless or minimal bases (gcr.io/distroless, alpine, chainguard) drop shells and libraries you never use. Fewer packages means fewer CVEs; no other single change cuts the list as much.
Generate an SBOM. Produce one at build time so you can answer "are we affected by the next Log4Shell?" in minutes instead of days.
Admission control. Use an admission controller (Kyverno, OPA Gatekeeper, or your registry's signing policy) to block images that were never scanned or signed from running in the cluster.
The noise problem
A real image yields dozens of findings, mostly not actionable. Treat them as equal and teams learn to ignore the scanner. Prioritize by three signals together:
- Severity: CRITICAL and HIGH first, but severity alone is a weak filter.
- Fix available: a CVE with a patched version is work you can finish today. One without is a note to watch.
- Reachability: is the vulnerable code path actually invoked? A CVE in a library your app links but never calls is far lower risk than one in your request-handling hot path. Tools with reachability analysis (Snyk, and increasingly others) cut the list dramatically.
The goal is a short queue of "severe, fixable, reachable" items your team actually clears, not a 400-row report nobody reads.
Questions people ask
What is the best container vulnerability scanner?
For most teams, Trivy: free, fast, and it covers OS packages, language dependencies, IaC, secrets, and licenses in one binary. Pick Grype if your pipeline is built around SBOMs, and Snyk Container if you want guided fixes and will pay for them.
Is Trivy or Grype more accurate?
For OS and language packages they are close, since both draw on distro trackers and GitHub Advisories. The real difference is scope: Trivy also checks misconfigurations and secrets, while Grype focuses on vulnerabilities and pairs with Syft SBOMs. Run both on one image and compare before standardizing.
Is Docker Scout free?
Partly. As of October 2026 Docker's Personal plan includes Docker Scout on one repository; Pro covers two, and Team ($15 per user per month billed annually) unlocks unlimited Scout-enabled repositories.
The call we'd make
Start with Trivy in CI, failing the build on HIGH/CRITICAL with ignore-unfixed on, and pair it with distroless base images to cut the finding count at the source. Turn on your registry's native scanning as a second layer, and add admission control so nothing unscanned reaches the cluster. Scanning says nothing about what a compromised container can do once it's running; that's where Kubernetes security best practices like RBAC scoping and network policies pick up the slack. If your organization can fund it and remediation speed matters more than tooling cost, add Snyk on top for its fix advice and reachability data. The tool choice matters less than the discipline around it: scan continuously, fail on what is fixable, shrink the image, and keep the queue short enough that people trust it.
Sources
Cilium vs Istio: eBPF Service Mesh Compared (2026)
A practitioner's comparison of Cilium's eBPF, sidecar-less dataplane against Istio's Envoy sidecar and ambient mesh models.
Terraform count vs for_each (and the Errors)
A practical look at when to reach for count, when for_each saves you, and the specific errors each meta-argument tends to throw.
More from DevOps
Explore more articles in this category
GitHub Actions Workflow Lockfiles: Pin Every Action, Including the Ones You Can't See
GitHub now records the exact commit of every direct and transitive action in .github/workflows/actions.lock. Here is how to adopt it, what it fixes that SHA pinning never did, and where it still leaks.
GitHub Actions macOS 14 Retirement: Fix Your Builds Before Nov 2
GitHub retires the macOS 14 runner image on November 2, and brownouts are already failing jobs. Here is how to find every macos-14 reference and move without breaking Xcode.
PHP2Shell (CVE-2026-109618, CVE-2026-109619): Patch Before the Bots Do
Two unauthenticated RCEs in PHP core, leaked a day before the patch, with exploit attempts already logged. Here is how to tell if you are exposed and what to do tonight.
You might have missed
Evergreen posts worth revisiting.