In my experience building production-grade Kubernetes clusters, the biggest blind spot is almost always the container image. We spend weeks hardening the network but then deploy a ‘latest’ tag image containing three critical CVEs. That is why I’ve integrated Trivy into every single one of my workflows. If you are looking for a step-by-step trivy container scanning guide, you’ve come to the right place.

Trivy, developed by Aqua Security, has become my go-to because it’s incredibly fast and doesn’t require a complex database setup to get started. Whether you are comparing it against other best open source container security scanners or just starting with DevSecOps, getting a handle on your image vulnerabilities is non-negotiable.

Prerequisites

Before we dive into the scanning process, ensure you have the following installed on your machine:

Step 1: Installing Trivy

I prefer using the official installation script because it handles the binary placement perfectly. Run the following command in your terminal:

curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin

Once installed, verify that the binary is accessible by checking the version:

trivy --version

Step 2: Running Your First Container Scan

The beauty of Trivy is its simplicity. You don’t need a config file for a basic scan. To scan a public image (e.g., Nginx), use the image command. As shown in the image below, the output will categorize vulnerabilities by severity.

trivy image nginx:latest

When I run this, Trivy downloads the vulnerability database from GitHub (the first run takes a few seconds longer) and then analyzes the OS packages and language-specific dependencies within the image.

Trivy scan output showing a table of vulnerabilities with severity levels
Trivy scan output showing a table of vulnerabilities with severity levels

Step 3: Filtering for Critical Vulnerabilities

In a real-world project, a standard scan can return hundreds of ‘Low’ or ‘Medium’ vulnerabilities that you might not have the bandwidth to fix immediately. To keep your signal-to-noise ratio high, I always filter for HIGH and CRITICAL levels.

trivy image --severity HIGH,CRITICAL nginx:latest

This allows you to focus on the flaws that actually pose a risk to your infrastructure. If you’re also managing your infrastructure as code, you might want to pair this with automating IaC security with Checkov to ensure your deployment manifests are just as secure as your images.

Step 4: Generating Machine-Readable Reports

If you are integrating this into a dashboard or a security audit, raw terminal output isn’t enough. Trivy supports JSON and Template formats. I personally use JSON for automation scripts.

trivy image -f json -o results.json nginx:latest

Step 5: Integrating Trivy into GitHub Actions

Manually running scans is a recipe for failure—you’ll eventually forget. I’ve automated my scanning using the official Trivy GitHub Action. Here is a snippet of how I set up my workflow file:


- name: Run Trivy vulnerability scanner
  uses: aquasecurity/trivy-action@master
  with:
    image-ref: 'my-app:${{ github.sha }}
    format: 'table'
    exit-code: '1' # This fails the build if vulnerabilities are found
    severity: 'CRITICAL,HIGH'

Setting exit-code: '1' is a power move. It effectively turns your security scan into a quality gate, preventing vulnerable code from ever reaching your registry.

Pro Tips for Better Scanning

Troubleshooting Common Issues

Issue: “Failed to download vulnerability database”
Solution: This is usually a network or proxy issue. Ensure your environment has access to github.com. If you are behind a strict corporate proxy, set the HTTP_PROXY environment variable before running the scan.

Issue: “Unable to find image locally”
Solution: If you are scanning a private image, make sure you have performed a docker login to the registry first. Trivy uses your local Docker credentials to pull the image.

What’s Next?

Now that you have a working container scanning pipeline, the next step is remediation. Don’t just find bugs—fix them. Start by switching to Distroless images or Alpine Linux to reduce the attack surface. Reducing the number of installed packages is the most effective way to reduce the number of CVEs Trivy finds.

If you’re looking for more ways to harden your stack, I recommend checking out my other guides on container security tools and IaC automation.