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: September 2026

A public S3 bucket or a Kubernetes pod running as root can expose client data faster than any outdated PHP library. Trivy IaC scanning closes that gap by checking Terraform, Kubernetes YAML, Dockerfiles, and CloudFormation before you apply changes. The same binary also scans container images and filesystems, which is why teams running Laravel on Docker treat it as a single security gate. This guide starts with IaC—the query most engineers actually type—then covers image scans, Ubuntu 24.04 setup, and CI wiring.

How do you run a Trivy IaC scan on Terraform and Kubernetes?

The trivy config subcommand is the core of any trivy iac scan. It parses HCL, YAML, JSON, and Dockerfiles, then evaluates them against built-in policies from CIS benchmarks and cloud provider best practices. You do not need a running cluster or cloud credentials—Trivy reads files locally or in CI.

Basic trivy config commands

Point Trivy at a directory or a single file. It walks the tree recursively and reports failed checks with remediation IDs you can search in the official Trivy misconfiguration docs.

# Scan all IaC under an infrastructure folder
trivy config ./infrastructure \
  --severity HIGH,CRITICAL \
  --format table

# Target Terraform modules only
trivy config ./infrastructure/terraform/main.tf \
  --severity HIGH,CRITICAL

# Kubernetes manifests before kubectl apply
trivy config ./k8s/overlays/production \
  --format sarif \
  --output k8s-iac-results.sarif

# Dockerfile best-practice checks alongside IaC
trivy config ./docker/Dockerfile \
  --severity MEDIUM,HIGH,CRITICAL

On a legal-tech portal or any system handling personal data, IaC scanning catches mistakes that package scanners miss. An RDS instance with publicly_accessible = true or a Security Group open to 0.0.0.0/0 on port 22 is a direct compliance risk under Nepal's data privacy requirements.

What file types does trivy iac support?

Trivy evaluates a wide set of IaC formats in one pass. This unified coverage is the main reason engineers choose it over container-only scanners.

  • Terraform and OpenTofu — HCL modules, variables, and resource blocks
  • Kubernetes — Deployments, Services, NetworkPolicies, Helm-rendered YAML
  • Dockerfile — USER directives, exposed ports, base image choices
  • CloudFormation and Azure ARM — JSON and YAML templates
  • Docker Compose — service definitions and volume mounts

For teams building multi-tenant SaaS on Laravel, run trivy config on namespace isolation manifests and Terraform modules that provision per-tenant databases. Tenant boundaries belong in code review and in automated policy checks.

Trivy IaC Scan PipelineTerraform HCL.tf modulesK8s YAMLmanifestsDockerfilebuild specsPolicy EngineCIS BenchmarksAWS / Azure / GCPCustom RegoComplianceReportAVD IDsSeverityFix guidance
Trivy IaC scanning aggregates Terraform, Kubernetes, and Dockerfile sources into one policy evaluation pass

How do you install Trivy on Ubuntu 24.04 for local and CI use?

Most production VPS hosts I maintain run Ubuntu 24.04 LTS with Apache or Nginx and PHP-FPM. Installing Trivy locally lets you run a trivy scan before pushing to GitLab CI. The APT repository from Aqua Security is the cleanest path on Ubuntu.

APT install on Ubuntu 24.04

# Ubuntu 24.04 (Noble) — official Trivy APT repo
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 /etc/apt/sources.list.d/trivy.list
sudo apt-get update
sudo apt-get install trivy

# Confirm version and pre-download vulnerability DB
trivy --version
trivy image --download-db-only

The first scan downloads a vulnerability database of roughly 500 MB to 1 GB. Plan disk space on CI runners accordingly. On bandwidth-constrained Kathmandu office networks, I schedule DB updates during off-peak hours via cron rather than on every pipeline run.

Binary install without root

On shared hosting or restricted accounts, download the release tarball from the Trivy GitHub releases page and place the binary in ~/bin. Add that directory to your PATH in .bashrc. This works on macOS dev machines and locked-down CI agents alike.

For a full PHP application stack walkthrough, see the Ubuntu server setup for PHP apps guide. Add Trivy as a post-provisioning step after Docker and PHP-FPM are in place.

How do you scan container images and PHP dependencies with Trivy?

Container scanning is the second half of the workflow. The command is trivy image, not trivy scan—though many engineers search for trivyscan and land on the same tool. Trivy inspects OS packages, language lockfiles, and embedded secrets inside the image layers.

Scanning Laravel and PHP Docker images

A typical Laravel production image based on php:8.4-fpm carries OS-level CVEs plus Composer dependencies from vendor/. Trivy reads both. Filter aggressively or your team will drown in low-severity noise.

# Production gate — HIGH and CRITICAL only, skip unfixed CVEs
trivy image \
  --severity HIGH,CRITICAL \
  --ignore-unfixed \
  --format table \
  registry.example.com/nepal-gift-card:latest

# Scan a locally built image before push
trivy image \
  --severity HIGH,CRITICAL \
  --ignore-unfixed \
  --scanners vuln,secret \
  myapp:local

# Filesystem scan of a Laravel project (no Docker required)
trivy fs . \
  --severity HIGH,CRITICAL \
  --skip-dirs vendor/node_modules/storage \
  --scanners vuln,secret,misconfig

Use multi-stage builds so build tools never reach the runtime image. Scan only the final stage in CI. That single change often cuts actionable findings by half on PHP and Node.js projects. The Laravel multi-stage Docker guide shows the pattern.

Trivy Image Scan WorkflowInputDocker imagetar archiveOCI registrytrivy image app:v1ScannersOS packagesComposer / npmSecret detectionLicense auditVuln DB lookupOutputTableJSONSARIFCycloneDX SBOMExit code 0/1
Trivy image scanning inspects OS packages, PHP Composer deps, and secrets before outputting reports or failing CI

How do you integrate Trivy IaC and image scans into GitLab CI?

Manual trivy scan iac runs do not scale across a team. Wire both trivy config and trivy image into your pipeline as blocking gates. For GitLab CI architecture patterns, see the CI/CD pipeline setup guide.

GitLab CI job for IaC and container gates

trivy-iac-scan:
  stage: test
  image: aquasec/trivy:latest
  script:
    - trivy config --exit-code 1 --severity HIGH,CRITICAL ./infra/
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"

trivy-image-scan:
  stage: test
  image: aquasec/trivy:latest
  needs: ["docker-build"]
  variables:
    TRIVY_DB_REPOSITORY: ghcr.io/aquasecurity/trivy-db
  script:
    - trivy image --exit-code 1 --severity CRITICAL \
        --ignore-unfixed $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
  allow_failure: false

Pin the Trivy image tag in production pipelines. Using :latest in CI can introduce surprise behaviour when Aqua ships a new release. I pin to a known version and bump it quarterly during maintenance windows.

GitHub Actions with SARIF upload

- name: Trivy IaC scan
  uses: aquasecurity/trivy-action@0.28.0
  with:
    scan-type: 'config'
    scan-ref: './infrastructure'
    severity: 'HIGH,CRITICAL'
    exit-code: '1'

- name: Trivy container scan
  uses: aquasecurity/trivy-action@0.28.0
  with:
    image-ref: 'ghcr.io/${{ github.repository }}:${{ github.sha }}'
    format: 'sarif'
    output: 'trivy-results.sarif'
    severity: 'CRITICAL'
    exit-code: '1'

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

SARIF upload puts findings in the GitHub Security tab. Non-engineers can triage without reading raw CI logs. Pair this with Gitleaks for secret detection to cover credentials Trivy might miss in git history.

CI/CD Trivy Security GatesGit PushMR / mainBuilddocker buildTrivy IaC Gatetrivy configFAIL = stopTrivy Image Gatetrivy imageFAIL = stopDeploy Proddep deploykubectl applyAlert Team
Dual Trivy gates for IaC misconfigurations and container CVEs block production deploy on failure

How do you filter false positives and manage Trivy exceptions?

No scanner is perfect. Trivy flags CVEs with no available patch, build-time tools absent from runtime, and cloud defaults your team already mitigates. A formal exception process keeps the tool trusted.

The .trivyignore file

Document every suppressed CVE with a reason and expiry date. Auditors on compliance-sensitive projects—such as the Notary Nepal portal—need that paper trail.

# .trivyignore — every entry needs a comment above it

# CVE-2024-1234: libxml2 in base image; app never parses external XML
# Expires: 2026-12-31
CVE-2024-1234

# AVD-AWS-0123: Intentional public ALB for marketing site
# Ticket: SEC-2026-089 | Expires: 2027-03-01
AVD-AWS-0123

Review the file monthly. Remove expired entries so old risks get re-evaluated. Never add blank suppressions without context.

Command flags that reduce noise

  1. --ignore-unfixed — skip CVEs with no upstream patch available
  2. --severity HIGH,CRITICAL — ignore LOW and MEDIUM in production gates
  3. --skip-dirs vendor,node_modules — for filesystem scans, avoid duplicate lockfile noise
  4. --ignorefile .trivyignore — explicit path when running from a subdirectory
  5. Multi-stage builds — scan only the runtime image layer, not the builder stage
Scan targetCommandKey flagsWhen to use
Terraform / OpenTofutrivy config--severity HIGH,CRITICALPre-apply IaC review and MR gates
Kubernetes YAMLtrivy config--format sarifCluster manifest validation before deploy
Production containertrivy image--ignore-unfixed --severity CRITICALFinal gate before live traffic
Laravel filesystemtrivy fs--skip-dirs vendor,node_modulesLocal dev feedback loop
SBOM exporttrivy image --format cyclonedx--output sbom.jsonClient audits and supply chain records

For broader IaC tooling comparisons, read the guide on tfsec, Checkov, and Terrascan. Trivy covers most of the same ground with one binary and one CI job.

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

Tool choice depends on scope, budget, and whether you need offline scanning. For agencies juggling WooCommerce stores and Laravel APIs across Nepal and abroad, one unified scanner reduces training overhead.

Scanner comparison at a glance

ToolIaC scanningContainer CVEsCostBest fit
TrivyYes — Terraform, K8s, DockerfileYesFree, open sourceTeams needing unified trivy iac + image coverage
GrypeNoYes — fastFree, open sourceContainer-only shops with separate IaC tooling
SnykYesYesFree tier limits; paid for teamsTeams wanting IDE plugins and fix PRs
CheckovYes — broad IaCLimitedFree, open sourceDeep IaC policy-as-code with custom Python checks

Budget-conscious Nepali SMEs often spend Rs 0 on security tooling licenses and Rs 5,000–15,000/month (~USD 37–110) on a VPS instead. Trivy fits that model. It runs fully offline after the DB download, which matters on networks with intermittent international bandwidth.

For context on why this investment matters locally, see why cybersecurity is crucial for Nepali businesses. The Linux system administration service covers hardening and scanner setup if your team lacks in-house DevOps capacity.

Scanner Selection GuideWhat do you need to scan?IaC + containers together?YESNOUse Trivytrivy iac + imageContainers only?YESNOUse GrypeFast CVE scansUse CheckovDeep IaC policiesSnyk fits teams needing IDE integration and automated fix PRs
Decision framework for trivy iac scanning versus container-only or IaC-only alternatives

Key Takeaways

  • Run trivy config ./infra/ on every merge request to catch Terraform and Kubernetes misconfigurations before apply.
  • Pair IaC scans with trivy image --severity CRITICAL --ignore-unfixed so container CVEs never reach production alone.
  • Install on Ubuntu 24.04 via the official APT repo and pre-download the vulnerability DB on CI runners.
  • Use .trivyignore with documented reasons and expiry dates—never silent suppressions.
  • Export SARIF or CycloneDX SBOM for audit trails required by compliance-sensitive client projects.
  • Start with CRITICAL-only gates, then tighten to HIGH as your team builds remediation muscle.

People Also Ask

What is the difference between trivy config and trivy image?

trivy config scans Infrastructure as Code files for misconfigurations like open security groups or missing encryption. trivy image scans container images for OS and application CVEs. Use both in CI for full coverage.

Can Trivy scan Terraform state files?

Trivy scans Terraform HCL source files, not .tfstate directly. Keep state in remote backends with encryption enabled. Scan the HCL that defines those backend settings with trivy config.

Does Trivy work offline after the first run?

Yes. After the initial vulnerability database download, Trivy runs without internet access. This makes it suitable for air-gapped environments and CI runners on local Nepali networks with limited bandwidth.

How often should you update the Trivy vulnerability database?

Update daily in CI via trivy image --download-db-only or rely on the official Trivy container image, which refreshes the DB on each run. Stale databases miss newly published CVEs within 24 to 48 hours.

Put Trivy IaC Scanning Into Production

Start with one trivy iac job on your next merge request pipeline. Add container scanning once the IaC gate is stable. The goal is not zero findings—it is blocking critical misconfigurations and exploitable CVEs before they touch client data. Parse JSON output with the JSON formatter when debugging failed pipeline reports. For Deployer-based Laravel sites, combine Trivy with zero-downtime deployment and dependency scanning for full coverage. Need help wiring security gates into your stack? Contact us about your deployment workflow, or reach out directly to discuss your infrastructure.

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

0 Comments

Leave a comment

Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

Quick Contact Options
Choose how you want to connect me: