🔍

Vulnerability in a Box

(VIB)

Continuous CVE scanning for your Docker fleet. Trivy scans your images, VictoriaMetrics stores the results, Grafana shows you what's exploitable — across every host.

Want this deployed and maintained for you? Review the engagement options

You've got dozens of images running across multiple hosts. Some of them haven't been rebuilt in months. VIB scans every image on every host with Aqua Trivy, pushes the results to VictoriaMetrics as time-series data, and gives you a Grafana dashboard that actually answers "what's exploitable right now?" — not just "here's a 2000-line JSON report."

⚡ Quick Start

git clone https://github.com/matijazezelj/vib.git && cd vib
cp .env.example .env   # set VICTORIAMETRICS_URL if pushing to external VM
docker compose up -d

Open Grafana at http://localhost:3001 and watch the scan results land.

First scan runs at startup (if STARTUP_SCAN=true), then on the configured interval (default every 6 hours).


🧠 How It Works

  1. Discover — VIB queries each configured Docker daemon for running containers and pulls the unique image list. Add ADDITIONAL_IMAGES for anything not currently running but you still want scanned.
  2. Scan — Each image gets handed to Trivy, which generates a full CVE report filtered by SEVERITY_FILTER.
  3. Push — Results are flattened into Prometheus-style metrics (per-image, per-CVE, per-severity) and pushed to VictoriaMetrics via the remote write endpoint.
  4. Visualize — A pre-built Grafana dashboard lights up: fleet-level severity counts, CVSS distribution, per-image drill-downs, fix availability.
  5. Optional — If AIB_BASE_URL is set, scan summaries get posted back to your Assets-in-a-Box inventory so vulnerable images are flagged on the dependency graph.

🛡️ What You Get

Component Technology Purpose
Scanner Aqua Trivy CVE detection, OS package + language deps
Storage VictoriaMetrics Time-series storage for vulnerability metrics
Visualization Grafana Pre-built dashboard, no JSON wrangling required
Orchestration Docker Compose Explicit services and one repeatable workflow
Multi-host Docker remote API Scan multiple daemons from one collector
Inventory hook AIB integration Optional — report findings back to asset inventory

📊 Dashboard

The bundled Grafana dashboard gives you:

Panel What it shows
Fleet severity overview Total CRITICAL/HIGH/MEDIUM/LOW counts across all images
Per-image CVE table Sortable by severity, fix availability, image age
CVSS score distribution Histogram across the fleet — see your real risk profile
Top vulnerable images The 10 images dragging down your security posture
Fix availability What you could patch today vs. waiting on upstream
Trend over time Are you getting better or worse?

Filter by host, image, namespace, or severity. The dashboard works whether you’re scanning 5 images or 500.


🌐 Multi-Host Scanning

Point one VIB instance at every Docker host you care about:

# .env
DOCKER_HOSTS=prod-web=tcp://10.0.1.10:2376,prod-db=tcp://10.0.1.20:2376,staging=tcp://10.0.2.10:2376

VIB will iterate through every host, pull the image list, dedupe, and scan once per unique image. Results are tagged with the host name so the dashboard can filter by host. If DOCKER_HOSTS is empty, VIB falls back to the local Docker socket.

TLS recommended. Expose remote Docker daemons via TLS, or tunnel through SSH/Tailscale. Don’t put a plain tcp:// Docker socket on a routable network.


⚙️ Configuration

VIB is configured entirely via environment variables. Defaults are sensible — set what you need, ignore the rest.

Variable Default Purpose
SCAN_INTERVAL_HOURS 6 How often to scan the fleet
STARTUP_SCAN true Run a scan immediately on container start
SEVERITY_FILTER CRITICAL,HIGH Comma-separated Trivy severities to report
ADDITIONAL_IMAGES (empty) Comma-separated images to scan even if not running
DOCKER_HOSTS (empty) name=tcp://host:port pairs; empty = local socket
VICTORIAMETRICS_URL http://victoriametrics:8428 Where to push metrics
AIB_BASE_URL (empty) Optional — AIB instance to report findings to
AIB_API_TOKEN (empty) Bearer token for AIB API

Example: production scan profile

SCAN_INTERVAL_HOURS=12
SEVERITY_FILTER=CRITICAL,HIGH,MEDIUM
ADDITIONAL_IMAGES=registry.internal/edge-proxy:latest,registry.internal/migrator:v3.2
DOCKER_HOSTS=app01=tcp://app01.internal:2376,app02=tcp://app02.internal:2376
AIB_BASE_URL=http://aib.internal:8080
AIB_API_TOKEN=${AIB_TOKEN}

🔍 Comparison

Tool Pros Cons Best for
VIB Multi-host scanning, time-series metrics, pre-built Grafana dashboard, one-command deploy Single scanner (Trivy), no exploit testing Anyone running Docker across multiple hosts who wants continuous visibility
Trivy standalone Same scanner under the hood, scriptable, full CLI You write your own scheduler, storage, dashboard, multi-host fan-out One-off scans, CI/CD pipelines
Grype Fast, good vuln DB, Anchore-backed Same DIY problem — no batteries-included dashboard or multi-host coordinator CI scanning, scriptable workflows
Anchore Enterprise Policy engine, compliance reports, enterprise support Commercial, complex, overkill for most homelabs/SMBs Regulated enterprises with compliance auditors
Docker Scout Integrated with Docker Hub, slick UI Tied to Docker’s hosted service, image-source focused, less control Teams that live in Docker Hub and want a managed experience

The honest pitch: VIB is Trivy with the operational scaffolding you’d build yourself if you had a free weekend — scheduler, multi-host loop, metric exporter, dashboard. If you already have all that, just use Trivy.


👥 Who This Is For

  • Homelabbers running dozens of containers who want to know when their stuff is rotting
  • Small ops teams without budget for Snyk/Anchore/Wiz but who need real vulnerability visibility
  • Platform engineers managing multi-host Docker fleets before/instead of moving to Kubernetes
  • Anyone who’s ever asked “wait, is anything on this host vulnerable right now?” and didn’t have an answer

Who This Is NOT For

  • Kubernetes-only shops — use a K8s-native scanner (Trivy Operator, Kubescape) instead
  • Teams already paying for Snyk/Wiz/Prisma — you’ve solved this problem
  • Anyone who needs exploit-chain analysis or runtime exploitation detection — VIB shows you CVEs, not active exploits (pair with SIB for that)

🔗 Pairs Well With

  • AIB — set AIB_BASE_URL to attach findings to your asset inventory
  • SIB — VIB tells you what’s vulnerable, SIB tells you when someone’s trying to exploit it
  • XIB — the umbrella that deploys VIB + CIB + PIB together with a single Grafana

📄 License

Apache 2.0 License — use it, modify it, build on it.

Ready to find out what's vulnerable?

View on GitHub

🚀 Need Help Getting Started?

Self-hosting is free and always will be. But if you'd rather have it deployed, configured, and maintained for you — I can help.