
August 20, 2026
9 min read
Table of Contents
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.
trivy image for container CVEs and trivy config for Terraform/Kubernetes misconfigurations. Integrate it into your GitLab CI or GitHub Actions pipeline as a blocking gate, using --severity HIGH,CRITICAL and --ignore-unfixed flags to prevent false positives from stalling legitimate development work in 2026.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.
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.
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.
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.
| Scenario | Trivy Command | Key Flags | Use Case |
|---|---|---|---|
| Production Container | trivy image | --ignore-unfixed --severity HIGH,CRITICAL | Pre-deploy gate for live services |
| Terraform Modules | trivy config | --security-checks config | Infrastructure compliance checks |
| Kubernetes Manifests | trivy config | --format sarif | Cluster security posture validation |
| Local Development | trivy fs | --skip-dirs vendor,node_modules | Fast feedback during coding |
| SBOM Generation | trivy image --format cyclonedx | --output sbom.json | Supply 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.
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.

