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.

SecurityContainersVulnerability scanning
What you learn

How to install Trivy, scan Docker images and the host filesystem, understand the results, and turn long reports into practical patch actions.

Best for

Self-hosted app operators, small teams on a VPS, and anyone who wants a fast free scanner before reaching for heavier enterprise security tooling.

Risk to watch

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.

Expected outcome: By the end, you will be able to scan both container images and your VPS packages, save the findings, and turn them into a short prioritized remediation list.

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 --version

The first real scan may take a little longer because Trivy downloads its vulnerability database. You can warm the cache deliberately:

trivy image --download-db-only

That 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 images

Scan one image by name:

trivy image nginx:alpine

Scan a specific app image from your stack:

trivy image ghcr.io/example/myapp:1.14.2

Focus the report on higher severity issues when you want a shorter first pass:

trivy image --severity HIGH,CRITICAL ghcr.io/example/myapp:1.14.2

Save 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.2

If you use Compose, scan the images shown in:

docker compose images

A 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 /var

To 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:

  1. 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.
  2. 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.
  3. 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.
  4. 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 -d

After patching, re-run the relevant Trivy scan to confirm the finding count changed as expected.

Warning: Do not “fix” scan output by hiding it or lowering severity thresholds without understanding the result. The point is to improve the system, not make the report quieter.

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.

Practical rule: The best scan is the one you can repeat. Keep your first Trivy workflow simple enough that it becomes part of normal maintenance instead of a one-time security scare.

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.