Skip to content
Go back

Trivy vs Grype vs Docker Scout

By SumGuy 11 min read
Trivy vs Grype vs Docker Scout

Your container images are full of vulnerabilities and you’re shipping them anyway

Don’t feel bad — everyone is. The question is whether you know about it, and whether knowing actually changes anything. Container image scanners are the answer to the first part. The second part is on you.

Three tools dominate this space: Trivy (Aqua Security), Grype (Anchore), and Docker Scout (Docker Inc.). They all scan container images for CVEs. They all produce a wall of anxiety-inducing output. They all cost nothing to get started. But they are meaningfully different in where they shine, where they stumble, and whether you’ll actually use them six months from now.

Here’s the honest breakdown.


Installation: First impressions matter

Trivy

Terminal window
# macOS
brew install aquasecurity/trivy/trivy
# Linux (script install)
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin
# Debian/Ubuntu
sudo apt-get install -y wget apt-transport-https gnupg lsb-release
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add -
echo deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main | sudo tee -a /etc/apt/sources.list.d/trivy.list
sudo apt-get update && sudo apt-get install trivy

Single binary. No daemon. No fussing with config files on day one. It just works — and that’s before you discover it also scans Kubernetes configs, Terraform, Helm charts, and your .env files for leaked secrets.

Grype

Terminal window
# macOS
brew install grype
# Linux (script install)
curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin
# Verify
grype version

Same energy as Trivy — single binary, curl-and-go. Grype pairs with Syft for SBOM generation; if you want that flow, install both:

Terminal window
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin

Docker Scout

Terminal window
# If you have Docker Desktop — it's already there
docker scout version
# CLI plugin (Linux servers without Desktop)
curl -fsSL https://raw.githubusercontent.com/docker/scout-cli/main/install.sh | sh
# Log in (required for most useful features)
docker login
docker scout quickview nginx:latest

Here’s the thing about Scout: it’s deeply married to Docker Hub and your Docker account. The free tier gives you local scanning and limited Hub image scanning. Serious policy enforcement and historical tracking live behind a paid org plan. That’s not inherently evil, but it’s the first place where friction shows up.

Installation winner: Trivy and Grype are neck-and-neck. Scout gets a penalty for requiring a login to do anything interesting.


Scanning Speed: Three images, one coffee

Let’s run all three against the same targets: nginx:latest, postgres:15, node:20-alpine.

Trivy

Terminal window
# First run downloads the vulnerability DB (~200MB) — subsequent runs are fast
trivy image nginx:latest
trivy image postgres:15
trivy image node:20-alpine

First run: 30–60 seconds (DB download). After that, under 10 seconds per image. Trivy caches the DB at ~/.cache/trivy and auto-updates it.

Grype

Terminal window
grype nginx:latest
grype postgres:15
grype node:20-alpine

Similar story — first run pulls the vulnerability DB (~100MB, smaller than Trivy’s). Subsequent scans: 5–15 seconds depending on image size. Grype’s DB lives at ~/.cache/grype.

Docker Scout

Terminal window
docker scout cves nginx:latest
docker scout cves postgres:15
docker scout cves node:20-alpine

Scout leans on Docker Hub’s analysis rather than a local DB, so you’re hitting the network for every scan unless the image is cached. On a fast connection this is fine. On a flaky home lab connection at 2 AM, it’s annoying.

Speed winner: Trivy and Grype are comparable after first run. Scout’s network dependency makes it less predictable.


CVE Coverage and False Positives

All three pull from roughly the same upstream sources — NVD, GitHub Advisory Database, OS vendor advisories (Debian, Ubuntu, Alpine, RHEL, etc.). The differences are in how they reconcile conflicts and how aggressively they filter false positives.

Trivy is comprehensive to a fault. It’ll surface CVEs that are technically present in a package but have no fix available, no real-world exploit, and no path to remediation. This isn’t wrong — it’s accurate. But it means your first scan of node:20-alpine will show 30+ “UNKNOWN” and “LOW” severity findings that you can’t do anything about today. Trivy’s --ignore-unfixed flag saves your sanity:

Terminal window
trivy image --ignore-unfixed --severity HIGH,CRITICAL node:20-alpine

Grype tends to produce slightly fewer false positives because it cross-references Anchore’s curated dataset, which applies more context around exploitability. The tradeoff is it can occasionally miss something Trivy catches. In practice on common images, the difference is noise.

Scout surfaces the “actionable” CVEs front and center, with clear guidance on what base image version would fix them. The signal-to-noise ratio feels better for day-to-day use — Docker has clearly optimized for “developer won’t ignore this because it’s too noisy.” The downside is you sometimes wonder what it’s not showing you.

CVE winner: For completeness, Trivy. For developer sanity, Scout. Grype splits the difference.


Output Formats: Because you’ll pipe this into something

Trivy’s buffet

Terminal window
# Table (default, human-readable)
trivy image nginx:latest
# JSON (for scripting/ingestion)
trivy image -f json -o results.json nginx:latest
# SARIF (for GitHub Advanced Security / VS Code)
trivy image -f sarif -o results.sarif nginx:latest
# SBOM in CycloneDX format
trivy image --format cyclonedx nginx:latest
# SBOM in SPDX format
trivy image --format spdx-json nginx:latest

Trivy also outputs to GitHub Security format, JUnit XML, and HTML. It’s embarrassingly feature-complete for output formats.

Grype’s approach

Terminal window
# Table (default)
grype nginx:latest
# JSON
grype -o json nginx:latest > results.json
# SARIF
grype -o sarif nginx:latest > results.sarif
# Generate SBOM first with Syft, then scan the SBOM
syft nginx:latest -o cyclonedx-json > sbom.json
grype sbom:./sbom.json

The Syft+Grype combo for SBOM-first scanning is legitimately elegant. You generate the inventory of what’s in the image (Syft), then check that inventory for vulnerabilities (Grype). This separates concerns cleanly and lets you store SBOMs for auditing without re-scanning.

Scout’s output

Terminal window
# Formatted table (default)
docker scout cves nginx:latest
# JSON
docker scout cves --format json nginx:latest
# SARIF
docker scout cves --format sarif nginx:latest
# Export SBOM
docker scout sbom nginx:latest

Scout’s table output is the most readable of the three out of the box — color-coded, grouped by severity, with clear remediation paths. Less output format variety than Trivy, but the defaults are better.


CI Integration: Where you’ll actually run this

GitHub Actions

Trivy has an official action:

.github/workflows/scan.yml
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: 'your-image:latest'
format: 'sarif'
output: 'trivy-results.sarif'
severity: 'HIGH,CRITICAL'
ignore-unfixed: true
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'trivy-results.sarif'

Grype in GitHub Actions:

.github/workflows/scan.yml
- name: Scan image with Grype
uses: anchore/scan-action@v3
with:
image: 'your-image:latest'
fail-build: true
severity-cutoff: high
output-format: sarif

Scout in GitHub Actions:

.github/workflows/scan.yml
- name: Docker Scout CVE scan
uses: docker/scout-action@v1
with:
command: cves
image: 'your-image:latest'
sarif-file: scout-results.sarif
summary: true
env:
DOCKER_SCOUT_HUB_USER: ${{ secrets.DOCKER_HUB_USERNAME }}
DOCKER_SCOUT_HUB_PASSWORD: ${{ secrets.DOCKER_HUB_TOKEN }}

Scout’s GitHub Action requires Docker Hub credentials in CI. Fine for open source projects with public images, mildly annoying for private infra.

Gitea Actions / Forgejo / Drone

For self-hosted CI runners (Gitea Actions, Forgejo, Woodpecker, Drone), Trivy and Grype are the clear winners. Both run as single binaries with no external service dependency — install once in a runner image or pull them on-demand:

gitea-workflow.yml
jobs:
scan:
runs-on: ubuntu-latest
steps:
- name: Install Trivy
run: |
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh \
| sh -s -- -b /usr/local/bin
- name: Scan image
run: |
trivy image \
--exit-code 1 \
--severity HIGH,CRITICAL \
--ignore-unfixed \
your-registry/your-image:${{ gitea.sha }}

Scout in self-hosted CI is a headache — you need Docker Hub creds, network access to Scout’s API, and you’re now dependent on Docker’s availability for your build pipeline. Hard pass for air-gapped or privacy-conscious setups.


IaC, Secret Detection, and the “Extra Credit” Round

This is where Trivy pulls away from the pack.

Terminal window
# Scan Terraform configs for misconfigurations
trivy config ./terraform/
# Scan Kubernetes manifests
trivy config ./k8s/
# Scan a Helm chart
trivy config ./helm/my-chart/
# Scan a git repo for secrets and IaC issues
trivy repo https://github.com/your-org/your-repo
# Scan filesystem for secrets (finds .env files, API keys, etc.)
trivy fs --scanners secret ./

Grype doesn’t do IaC scanning — it’s focused on vulnerability detection. Scout doesn’t either. If you want one tool that handles CVEs and your Terraform state file that someone accidentally committed in 2023, Trivy wins by default.


Offline and Air-Gapped Environments

Home labbers running isolated networks will care about this.

Trivy has explicit air-gap support:

Terminal window
# Download DB on a connected machine
trivy image --download-db-only
# Copy the DB to your air-gapped machine
# Default location: ~/.cache/trivy/db/
# Scan with local DB (skip update check)
trivy image --skip-db-update --skip-java-db-update nginx:latest

Grype also supports offline mode:

Terminal window
# Update DB on connected machine
grype db update
# Copy ~/.cache/grype/db/ to air-gapped machine
# Disable auto-update
GRYPE_DB_AUTO_UPDATE=false grype nginx:latest

Scout is not designed for air-gapped use. It relies on Docker’s cloud infrastructure for most of its value. Running Scout offline is possible in theory but loses most useful features in practice.

Offline winner: Trivy — it has the most mature air-gap workflow and explicit documentation for it.


Cost

ToolPersonal/Home LabCI (OSS/self-hosted)Enterprise
TrivyFree, OSSFreeFree (Aqua Platform is separate/paid)
GrypeFree, OSSFreeFree (Anchore Enterprise is separate/paid)
Docker ScoutFree (limited Hub images)Free for public reposPaid org plan required for policy, history, team features

Trivy and Grype are genuinely free, forever. Scout is free until you want the features that make it worth using at scale. That’s not surprising — Docker needs revenue — but it shapes the decision for team environments.


The Verdict

Use Trivy if:

Use Grype if:

Use Docker Scout if:

Skip buying into Scout for serious CI scanning — the credential dependency and cloud reliance make it the wrong tool for automated pipelines that need to be reliable at 3 AM when Docker’s API has a blip.

And honestly? None of these replace patching. Knowing you have CVE-2024-whatever in your base image is only useful if you actually rebuild with an updated image. Scanner output without a rebuild + redeploy pipeline is just a longer to-do list. Set up automated base image rebuilds (Renovate Bot, Watchtower for non-critical services, or a weekly cron that pulls and rebuilds) alongside whatever scanner you pick.

The scanner tells you the building is on fire. You still have to pull the alarm.


Quick Reference

Terminal window
# Trivy — scan and only fail on fixable HIGH/CRITICAL
trivy image --ignore-unfixed --severity HIGH,CRITICAL --exit-code 1 nginx:latest
# Grype — scan with Syft SBOM workflow
syft nginx:latest -o cyclonedx-json | grype --fail-on high
# Scout — quick overview with remediation hints
docker scout recommendations nginx:latest

Pick your scanner, wire it into CI, and then go fix the actual vulnerabilities. The tool is the easy part.


Share this post on:

Send a Webmention

Written about this post on your own site? Send a webmention and it'll show up above once verified.


Previous Post
Backblaze B2 + rclone: Tiered Backup at Real-World Costs
Next Post
Kdenlive vs DaVinci Resolve on Linux

Discussion

Powered by Garrul . Sign in with GitHub or Google, or post anonymously.

Related Posts