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.
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
- Discover — VIB queries each configured Docker daemon for running containers and pulls the unique image list. Add
ADDITIONAL_IMAGESfor anything not currently running but you still want scanned. - Scan — Each image gets handed to Trivy, which generates a full CVE report filtered by
SEVERITY_FILTER. - Push — Results are flattened into Prometheus-style metrics (per-image, per-CVE, per-severity) and pushed to VictoriaMetrics via the remote write endpoint.
- Visualize — A pre-built Grafana dashboard lights up: fleet-level severity counts, CVSS distribution, per-image drill-downs, fix availability.
- Optional — If
AIB_BASE_URLis 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_URLto 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.