How to Scan Docker Images and VPS Packages for Vulnerabilities with Trivy
Find known security issues in your containers and server packages with Trivy so patching decisions are based on evidence instead of vague worry.
How to install Trivy, scan Docker images and the host filesystem, understand the results, and turn long reports into practical patch actions.
Self-hosted app operators, small teams on a VPS, and anyone who wants a fast free scanner before reaching for heavier enterprise security tooling.
A vulnerability scan can create false comfort if you treat “fewer findings” as the whole security story and ignore exposed ports, bad secrets, or weak update habits.
Before you begin
- A Linux VPS or workstation with Docker installed.
- Permission to install a CLI scanner and read local container images.
- Comfort with command-line output that may look noisy at first.
- A maintenance window in mind if you plan to patch after scanning.
Vulnerability scanning is most useful when it feeds a sane patch routine. The goal is not to chase every low-severity item instantly. The goal is to spot high-risk issues, understand which packages or images they affect, and update with enough care that you do not break the apps you are trying to protect.
Step 1: Understand what Trivy does well
Trivy is a popular open-source scanner that can inspect:
- Docker images
- Running containers
- Local filesystems
- Git repositories and configuration files
- Operating system packages inside images or on disk
It is a strong fit for self-hosting because it is easy to start with and does not require a large platform around it. For a small VPS stack, that means you can get useful visibility quickly.
Remember what Trivy is not. It does not prove your system is safe. It does not know whether you exposed a service publicly on purpose, whether your secrets leaked in Git, or whether your firewall is right. It is one important signal, not the whole job.
Step 2: Install Trivy and warm the vulnerability database
On Ubuntu or Debian, you can install from the official repository. Example:
sudo apt-get update
sudo apt-get install -y wget 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 -y trivy
trivy --versionThe first real scan may take a little longer because Trivy downloads its vulnerability database. You can warm the cache deliberately:
trivy image --download-db-onlyThat is useful before automation or before a maintenance window where you want scans to start quickly.
Step 3: Scan Docker images you actually run
List local images first:
docker imagesScan one image by name:
trivy image nginx:alpineScan a specific app image from your stack:
trivy image ghcr.io/example/myapp:1.14.2Focus the report on higher severity issues when you want a shorter first pass:
trivy image --severity HIGH,CRITICAL ghcr.io/example/myapp:1.14.2Save results to a file for later review:
mkdir -p security-reports
trivy image --severity HIGH,CRITICAL --format table -o security-reports/myapp-image-scan.txt ghcr.io/example/myapp:1.14.2If you use Compose, scan the images shown in:
docker compose imagesA practical beginner habit is to start with:
- The reverse proxy image
- The main application image
- The database image if you manage updates yourself
- Any less common third-party images from smaller vendors
Step 4: Scan VPS packages and the host filesystem
To scan the local root filesystem for OS packages and known issues:
sudo trivy fs --scanners vuln /That can be noisy on a large server, so a more targeted first run is often easier:
sudo trivy fs --scanners vuln /usr /etc /varTo save a focused report with higher severities only:
sudo trivy fs --scanners vuln --severity HIGH,CRITICAL --format table -o security-reports/vps-fs-scan.txt /If you want to scan a checked-out repository for both vulnerabilities and common misconfigurations, you can also run:
trivy config .
trivy fs .That is useful for spotting risky Dockerfiles, Terraform, Kubernetes YAML, or leaked package issues inside a project directory.
Step 5: Turn the report into a patch plan
A long vulnerability report can feel overwhelming. Use this order instead:
- Patch internet-facing services first. A critical issue in your public reverse proxy matters more urgently than a medium issue in a container that never leaves a private network.
- Prioritize fixes with an available upgrade path. Some findings have no current vendor fix. Note them, then focus on what you can actually remediate now.
- Check whether the vulnerable package is really reachable. A package can appear in an image without being used in a way that matters to your threat model, though you should still keep it on your list.
- Update one service at a time. Avoid turning a security review into a chaotic bulk upgrade.
Helpful follow-up commands:
apt list --upgradable
docker compose pull
docker compose up -dAfter patching, re-run the relevant Trivy scan to confirm the finding count changed as expected.
Expected outcomes
- You can scan a Docker image and identify high-priority findings.
- You can scan VPS packages from the filesystem and save the results.
- You know which issues are internet-facing, patchable now, or worth watching until a vendor ships a fix.
- You have a repeatable command set for future monthly or pre-deploy checks.
Rollback and recovery notes
Scanning itself is low risk. The main risk comes from rushed patching afterward. Before applying updates:
- Take a backup or snapshot for stateful services.
- Pin the current image tag so rollback is clear.
- Update one component at a time.
If an image update breaks the app, roll back to the previous known good tag or digest and restore data if the new version migrated it. If an OS package update causes trouble, review package history and consider reverting from a snapshot or provider image backup if the change was severe.
Troubleshooting common Trivy issues
Trivy cannot connect to Docker.
Run the command as a user with Docker access, or use sudo if that fits your environment.
The scan takes a long time.
The first database download can be slow. Later scans are usually faster. You can also narrow scope or severity for the first pass.
I see lots of unfixed vulnerabilities.
That often means the upstream image or package repository has not shipped a fix yet. Track the issue, reduce exposure, and watch for vendor updates rather than assuming you missed a command.
The report is huge and hard to use.
Start with --severity HIGH,CRITICAL and save output to a file. Focus on internet-facing services first.
Host scans show findings in paths I do not care about.
Target only the directories or repositories relevant to your deployment, or archive the full report and create a smaller remediation list from it.
What to do next
Once you can see risky packages and images, the next operational cleanup is preventing logs from quietly filling the disk underneath an otherwise healthy stack. Continue with How to Manage Docker Log Size with logrotate and json-file Limits.
