Kokil Thapa - Professional Web Developer in Nepal
Freelancer Web Developer in Nepal with 15+ Years of Experience

Kokil Thapa is an experienced full-stack web developer focused on building fast, secure, and scalable web applications. He helps businesses and individuals create SEO-friendly, user-focused digital platforms designed for long-term growth.

Trivy: Scan Containers and IaC for Vulnerabilities

By Kokil Thapa | Last reviewed: August 2026

Shipping code without automated security checks is a liability, whether you are deploying a Laravel API or a WordPress eCommerce store. Using Trivy: Scan Containers and IaC for Vulnerabilities gives you a single, open-source binary that detects CVEs in OS packages, language-specific dependencies, and misconfigurations in infrastructure code before they reach production. This guide covers the exact commands, CI/CD integration patterns, and filtering strategies I use to keep client deployments secure without slowing down delivery.

How do you install and configure Trivy for container scanning?

Before you can integrate security into your workflow, you need a reliable local installation. While many developers rely solely on CI, having Trivy locally allows you to catch issues before pushing code. For those of us working on Laravel projects or managing Dockerized PHP-FPM environments, local feedback loops are essential for maintaining velocity.

Installation methods for 2026

Trivy is distributed as a standalone binary, which makes it incredibly portable across Linux servers, macOS development machines, and CI runners. Avoid installing via npm or pip wrappers; use the official release artifacts or package managers to ensure you have the latest vulnerability database updates.

# Install on Ubuntu/Debian (Recommended for production servers)
sudo apt-get install wget apt-transport-https gnupg lsb-release
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | gpg --dearmor | sudo tee /usr/share/keyrings/trivy.gpg > /dev/null
echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] 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

# Verify installation and DB version
trivy --version
trivy image --download-db-only

On shared hosting or restricted VPS environments where you lack root access, download the tarball directly from the GitHub releases page. Extract it to /usr/local/bin or your user's ~/bin directory. The first run downloads the vulnerability database (~1GB), so plan for this initial latency in your provisioning scripts.

Developer CLItrivy image app:latestTrivy EngineOS Pkg ScannerLang Dep ScannerSecret DetectorLicense CheckerReport OutputJSON / SARIF / Table
Trivy processes container images through multiple specialized scanners before generating actionable reports

Scanning Docker images effectively

The most common use case is scanning built container images. In my experience working on production Laravel applications, base images like php:8.4-fpm often carry dozens of low-severity CVEs that are irrelevant to your application logic. Filtering is mandatory to avoid alert fatigue.

# Scan with practical production filters
trivy image \
  --severity HIGH,CRITICAL \
  --ignore-unfixed \
  --format table \
  myregistry.com/nepal-law-portal:2026.08

# Export to JSON for CI parsing
trivy image \
  --severity HIGH,CRITICAL \
  --format json \
  --output results.json \
  myregistry.com/nepal-law-portal:2026.08

The --ignore-unfixed flag is critical. It hides vulnerabilities that have no available patch yet. Without it, your team will waste hours researching CVEs that cannot be resolved by upgrading packages. Focus only on what you can actually fix today.

How does Trivy detect misconfigurations in Infrastructure as Code?

Security isn't just about outdated packages; it's also about how you configure your infrastructure. When building legal-tech portals or handling sensitive client data, a misconfigured S3 bucket or an overly permissive Kubernetes pod spec is often more dangerous than a library CVE. Trivy’s config subcommand scans Terraform, CloudFormation, Kubernetes YAML, and Dockerfiles against built-in policies derived from CIS benchmarks and AWS/Azure/GCP best practices.

Scanning Terraform and Kubernetes

Point Trivy directly at your repository root or specific directories containing IaC files. It recursively parses HCL, YAML, and JSON configurations.

# Scan Terraform modules for security issues
trivy config ./infrastructure/terraform \
  --severity HIGH,CRITICAL \
  --format table

# Scan Kubernetes manifests before applying
trivy config ./k8s-manifests/ \
  --security-checks config \
  --format sarif \
  --output k8s-audit.sarif

For teams managing multi-tenant SaaS architectures or complex deployment pipelines, integrating these checks prevents drift between your intended security posture and actual cloud resources. If you are exploring multi-tenant SaaS architectures, strict IaC scanning ensures tenant isolation policies are codified and verified automatically.

Terraform HCLK8s YAMLDockerfilePolicy EngineCIS BenchmarksCustom RegoComplianceReportFailed ChecksRemediation IDs
Trivy aggregates multiple IaC sources and evaluates them against centralized security policies

Customizing policies for Nepal-specific compliance

While global CIS benchmarks cover most bases, projects handling Nepali citizen data or financial transactions may require additional constraints. You can write custom Rego policies to enforce region-specific rules, such as ensuring databases are never publicly accessible or that encryption-at-rest is mandatory for all storage buckets. Place these in a .trivy/policies directory within your repo, and Trivy loads them automatically during config scans.

How do you integrate Trivy into GitLab CI and GitHub Actions?

Manual scanning doesn't scale. You need automated gates in your CI/CD pipeline. Whether you use GitLab CI (common among Nepal-based dev teams for self-hosted runners) or GitHub Actions, Trivy provides official actions and container images that simplify integration. For deeper context on pipeline architecture, see my notes on CI/CD pipeline setup.

GitLab CI job configuration

Add this job to your .gitlab-ci.yml. It runs after the build stage but before deployment, failing the pipeline if critical vulnerabilities are found.

trivy-scan:
  stage: test
  image: aquasec/trivy:0.60.0
  variables:
    TRIVY_DB_REPOSITORY: ghcr.io/aquasecurity/trivy-db
  script:
    # Scan the built image
    - trivy image --exit-code 1 --severity CRITICAL $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
    # Scan IaC changes
    - trivy config --exit-code 1 --severity HIGH,CRITICAL ./infra/
  allow_failure: false
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"

Note the TRIVY_DB_REPOSITORY variable. In regions with intermittent connectivity to default CDNs, pointing to a reliable mirror prevents random pipeline failures. I’ve configured this for several clients running self-hosted GitLab runners in Kathmandu to avoid timeout issues during peak hours.

GitHub Actions workflow

For GitHub-hosted projects, use the official action. It handles caching and SARIF upload natively.

- name: Run Trivy vulnerability scanner
  uses: aquasecurity/trivy-action@master
  with:
    image-ref: 'ghcr.io/${{ github.repository }}:${{ github.sha }}'
    format: 'sarif'
    output: 'trivy-results.sarif'
    severity: 'HIGH,CRITICAL'
    exit-code: '1'

- name: Upload Trivy scan results to GitHub Security tab
  uses: github/codeql-action/upload-sarif@v3
  if: always()
  with:
    sarif_file: 'trivy-results.sarif'

Uploading SARIF files integrates findings directly into GitHub’s Security Overview, making triage visible to non-engineers and project managers without requiring them to read raw CI logs.

Build Imagedocker buildTrivy GateImage ScanIaC Config ScanSecret DetectionFAIL → Stop PipelineDeploy Proddep deployNotify Team
Automated Trivy gate blocks deployments when critical vulnerabilities or misconfigurations are detected

How do you handle false positives and manage vulnerability exceptions?

No scanner is perfect. Trivy will occasionally flag vulnerabilities that don’t apply to your runtime environment or are mitigated by other controls. Blindly accepting every finding erodes trust in the tool. Establishing a formal exception process is as important as the scanning itself.

Using .trivyignore for justified exceptions

Create a .trivyignore file in your repository root. Document every ignored CVE with a reason and expiration date. This turns ad-hoc suppressions into auditable decisions.

# CVE-2024-1234: Affects libxml2 but our app never parses untrusted XML
# Mitigated by input validation middleware
# Expires: 2026-12-31
CVE-2024-1234

# CVE-2025-5678: False positive in Alpine 3.20, fixed upstream but not in DB
# Ticket: JIRA-SEC-442
CVE-2025-5678

Review this file monthly. Expired entries force re-evaluation. On legal-tech projects where audit trails matter, this file becomes part of your compliance evidence. Never add entries without documentation; future maintainers (or auditors) need context to understand why a risk was accepted.

Distinguishing runtime vs build-time dependencies

A common source of noise is vulnerabilities in build tools that aren’t present in the final runtime image. Use multi-stage Docker builds to separate concerns, then scan only the final stage. If you must scan intermediate stages for debugging, tag them explicitly and exclude them from production gates. This distinction alone typically reduces actionable findings by 40–60% in PHP and Node.js applications.

ScenarioTrivy CommandKey FlagsUse Case
Production Containertrivy image--ignore-unfixed --severity HIGH,CRITICALPre-deploy gate for live services
Terraform Modulestrivy config--security-checks configInfrastructure compliance checks
Kubernetes Manifeststrivy config--format sarifCluster security posture validation
Local Developmenttrivy fs--skip-dirs vendor,node_modulesFast feedback during coding
SBOM Generationtrivy image --format cyclonedx--output sbom.jsonSupply chain transparency & audits

When should you choose Trivy over Grype, Snyk, or Dockle?

Trivy isn’t the only option, but it occupies a sweet spot for full-stack teams managing both containers and IaC. Understanding its trade-offs helps you justify the choice to stakeholders or decide when another tool fits better.

Comparison with alternatives

  • vs. Snyk: Snyk offers superior IDE integration and developer-friendly remediation advice, but requires authentication and has usage limits on free tiers. Trivy is fully offline-capable and unrestricted, making it ideal for air-gapped environments or budget-constrained projects common in Nepal’s SME sector.
  • vs. Grype: Grype focuses exclusively on container/package vulnerabilities and excels at speed. However, it lacks native IaC scanning. If you only care about CVEs in Docker images and already have separate tooling for Terraform/K8s, Grype is lighter. Trivy’s advantage is unified coverage.
  • vs. Dockle: Dockle specializes in Dockerfile best practices and CIS Docker benchmarks. It complements Trivy rather than replacing it. Many teams run both: Dockle for image hygiene, Trivy for vulnerabilities and IaC.

For agencies or freelancers juggling diverse client stacks—from WooCommerce stores to custom Laravel APIs—Trivy’s breadth reduces tool sprawl. Maintaining one scanner that handles images, configs, filesystems, and SBOMs simplifies training and pipeline maintenance. When advising clients on cybersecurity priorities, I recommend starting with Trivy because it delivers immediate value across multiple domains without licensing friction.

Start: Security Need?Need IaC + Container Scanning?YESNOUse TrivyUnified CoverageContainers Only?YESNOUse GrypeFaster CVE FocusSnyk /Dockle
Decision framework for selecting the right security scanner based on scope and requirements

Implementing Trivy for Secure Deployments

Adopting Trivy: Scan Containers and IaC for Vulnerabilities transforms security from an afterthought into a continuous, automated practice. Start by integrating image scans into your existing CI pipeline with conservative severity thresholds, then expand to IaC and filesystem checks as your team matures. Remember that the goal isn’t zero vulnerabilities—it’s informed risk management with clear ownership and remediation paths. If you need help designing a security-first deployment workflow for your Laravel, WordPress, or custom infrastructure project, reach out to discuss your specific requirements.

Frequently Asked Questions

Trivy is an open-source vulnerability scanner for containers, filesystems, Git repositories, and Infrastructure as Code. It detects CVEs in OS packages and language-specific dependencies without requiring a running container or external database server.

Yes. Trivy is Apache 2.0 licensed and completely free for personal and commercial use. There are no licensing fees, unlike Snyk or Aqua Enterprise. Paid options exist only for managed cloud services or enterprise support contracts if your organization requires them.

Add the Aqua Security APT repository and install via apt. Run wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | gpg --dearmor | sudo tee /usr/share/keyrings/trivy.gpg > /dev/null, add the repo to sources.list, then run sudo apt update && sudo apt install trivy. This installs the latest stable binary with automatic updates through the system package manager.

Trivy scans static Docker images, not live processes. Use trivy image myapp:latest to analyze layers before deployment. For runtime inspection, combine Trivy with tools like Falco. In my experience, scanning at build time catches issues earlier and prevents vulnerable images from reaching production servers.

Yes. Run trivy config /path/to/iac to scan Terraform, CloudFormation, Kubernetes manifests, and Helm charts. It checks for misconfigurations like public S3 buckets, missing encryption, privileged containers, and excessive permissions. This makes it valuable for legal-tech portals where compliance and data protection matter as much as application code vulnerabilities.

Trivy covers more targets (containers, IaC, SBOMs) in one tool versus Grype's container-only focus. Unlike Snyk, Trivy needs no account or API key for basic scanning. Snyk offers better fix recommendations and prioritization, but Trivy wins for offline CI pipelines and budget-sensitive Nepal projects where Rs 0 matters more than premium features.

Fail on CRITICAL and HIGH by default using --severity CRITICAL,HIGH --exit-code 1. Allow MEDIUM with remediation tickets. LOW can be tracked separately. On client projects handling sensitive legal documents, I sometimes include MEDIUM failures for authentication-related packages. Adjust thresholds based on your risk tolerance and compliance requirements rather than following generic advice blindly.

Add a job using aquasec/trivy-action@master or the official Docker image. Configure it to scan built artifacts before pushing to registry. Cache the vulnerability database between runs to avoid repeated downloads. In Deployer 7 workflows I maintain, this runs after composer install but before deployment, catching regressions early without slowing release cycles significantly.

Trivy uses its own vulnerability database aggregated from NVD, GitHub Advisory, and other sources, while npm audit relies solely on the npm registry. Databases update on different schedules and may classify severity differently. Always investigate discrepancies manually rather than assuming either source is definitively correct, especially for transitive dependencies in complex Laravel or Node applications.

Update before each CI run or daily in automated pipelines using trivy db download. The database grows continuously as new CVEs are published. Stale databases miss recent vulnerabilities. On shared EC2 infrastructure I manage, scheduled nightly updates ensure consistent results across multiple sites without manual intervention or unexpected scan failures during business hours.

Yes. Run trivy image --format spdx-json -o sbom.spdx.json myapp:latest to generate SPDX-compliant Software Bill of Materials. CycloneDX format is also supported via --format cyclonedx. This satisfies increasing regulatory requirements and helps track third-party components in legal-tech platforms where audit trails and dependency transparency are contractually required.

Create a .trivyignore file listing CVE IDs or package names to exclude. Use comments explaining why each entry is ignored. Place this file in your repository root so ignores travel with code. Review quarterly to remove resolved issues. Blanket ignores defeat the purpose; document rationale for auditors and future maintainers who inherit the project.

Yes. Download the database beforehand with trivy db download and copy the cache directory to air-gapped systems. Set TRIVY_CACHE_DIR to point to the offline location. This is essential for government or financial clients in Nepal with restricted network policies. Verify database freshness regularly since offline environments cannot auto-update during scans.

Large images with many layers slow analysis. Multi-stage builds reduce final image size and scan time. Enable --skip-dirs for vendor directories already scanned elsewhere. Parallelize scans across matrix jobs. On resource-constrained runners, pre-pull the Trivy image to avoid download overhead. Caching the database between pipeline runs typically cuts execution time by 60-80 percent.

Export JSON results and transform them into executive summaries showing total findings by severity, affected components, and remediation status. Avoid raw CVE lists. For legal-tech clients, map vulnerabilities to business risks like data exposure or compliance violations rather than technical jargon. Provide actionable next steps with estimated effort in NPR or USD so decision-makers can prioritize fixes against development budgets.

Share this article

Quick Contact Options
Choose how you want to connect me: