tutorial

Monitoring Docker Image Layer Analysis with Dive and Vigilmon

Dive gives you deep visibility into Docker image layers — but the builds and CI jobs that feed it still need monitoring. Here's how to keep your Dive integration healthy with Vigilmon.

Dive is an open-source tool for exploring Docker image layers, analyzing what each layer adds to an image, and finding wasted space from unnecessary files, caches, and duplicate packages. Teams use it in CI to enforce image efficiency — failing builds when too much space is wasted. But like any CI integration, the Dive step can silently stop running. Vigilmon helps you monitor the jobs and services that power your Dive workflow so a broken efficiency gate never ships bloated images to production.

What You'll Set Up

  • Cron heartbeat confirming Dive analysis runs on every image build
  • HTTP monitor for a Dive results dashboard or API if your team centralizes reports
  • Slack or email alerts when image analysis goes silent

Prerequisites

  • Dive installed in your CI pipeline (docker run wagoodman/dive:latest or binary)
  • A free Vigilmon account
  • Shell access to your CI runner

Step 1: Add a Heartbeat to Your Dive CI Step

The simplest monitoring is a heartbeat ping at the end of a successful Dive analysis. If the ping stops arriving, Vigilmon pages your team.

  1. Log in to vigilmon.online and click Add Monitor.
  2. Select Cron Heartbeat.
  3. Set the expected interval to match your build frequency — 60 minutes for hourly builds, 1440 minutes (24 hours) for nightly builds.
  4. Copy the heartbeat URL: https://vigilmon.online/heartbeat/abc123.

Add the ping to your analysis script:

#!/bin/bash
set -e

IMAGE=$1
EFFICIENCY_THRESHOLD=${2:-0.85}

echo "Analyzing image layers: $IMAGE"
CI=true dive "$IMAGE" --ci \
  --highestUserWastedPercent 0.15 \
  --lowestEfficiency "$EFFICIENCY_THRESHOLD"

echo "Dive passed — pinging Vigilmon"
curl -s "https://vigilmon.online/heartbeat/abc123"

In a GitHub Actions workflow:

- name: Analyse image layers with Dive
  run: |
    docker run --rm \
      -v /var/run/docker.sock:/var/run/docker.sock \
      wagoodman/dive:latest \
      --ci \
      --highestUserWastedPercent 0.15 \
      ${{ env.IMAGE_NAME }}

- name: Ping Vigilmon heartbeat
  if: success()
  run: curl -s https://vigilmon.online/heartbeat/abc123

If Dive fails the efficiency check or the pipeline errors before the ping, Vigilmon alerts — meaning someone has to look at the build before images continue shipping.


Step 2: Enforce the Efficiency Gate with Exit Codes

Dive supports a --ci flag that exits non-zero when images exceed your waste thresholds. Make sure your CI is wired to treat this as a build failure — otherwise Dive becomes decorative.

# .dive-ci.yaml — checked into the repo
rules:
  lowestEfficiency: 0.85
  highestWastedBytes: "50MB"
  highestUserWastedPercent: 0.15

Reference this config in your pipeline:

dive --ci --ci-config .dive-ci.yaml "$IMAGE"

Only ping the Vigilmon heartbeat when Dive exits 0 — a non-zero exit means the image failed the gate and you want that alert to surface through your CI notification channel, not be masked by a successful heartbeat.


Step 3: Monitor a Centralized Dive Results Service

If your team aggregates Dive reports — showing efficiency trends over time, comparing layers across image versions — expose a health endpoint for that service.

  1. In Vigilmon, click Add MonitorHTTP / HTTPS.
  2. Enter your results service URL: https://dive-reports.internal.example.com/health.
  3. Set Check interval to 5 minutes.
  4. Set Expected HTTP status to 200.
  5. Click Save.

A minimal Go health handler for a results server:

http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
    // Check database connectivity
    if err := db.Ping(); err != nil {
        w.WriteHeader(http.StatusServiceUnavailable)
        json.NewEncoder(w).Encode(map[string]string{"status": "db_error"})
        return
    }
    w.WriteHeader(http.StatusOK)
    json.NewEncoder(w).Encode(map[string]string{"status": "ok"})
})

If the results service goes down, Dive still runs in CI but nobody can see historical trends or receive reports — which defeats the point of centralizing analysis.


Step 4: Monitor the Docker Socket Service

Dive requires access to the Docker daemon to read image layers. If you run Dive in a containerized environment and the Docker socket mount breaks, Dive fails silently or exits with an error that looks like a scan failure rather than an infrastructure problem.

Add a TCP monitor for the Docker daemon port if your CI exposes Docker over TCP:

  1. In Vigilmon, click Add MonitorTCP.
  2. Enter your Docker host and port: docker-host.example.com : 2376.
  3. Set Check interval to 2 minutes.
  4. Click Save.

For local Unix socket access (more common), rely on the heartbeat monitor — if the socket is inaccessible, the Dive step fails and the heartbeat doesn't ping.


Step 5: Track Image Size Trends with an API Endpoint

Expose image efficiency metrics from your Dive reports so Vigilmon can optionally check a computed health status:

@app.route('/api/dive/health')
def dive_health():
    # Check last 24 hours of analyses
    recent = db.query("""
        SELECT image, efficiency, wasted_bytes, analysed_at
        FROM dive_results
        WHERE analysed_at > NOW() - INTERVAL '24 hours'
        ORDER BY analysed_at DESC
        LIMIT 1
    """)
    if not recent:
        return {'status': 'no_recent_analysis', 'ok': False}, 503
    if recent['efficiency'] < 0.80:
        return {'status': 'low_efficiency', 'efficiency': recent['efficiency']}, 200
    return {'status': 'ok', 'efficiency': recent['efficiency']}, 200

This endpoint returns 503 when no analysis has run in 24 hours — Vigilmon will alert your team.


Step 6: Configure Alerts for Image Bloat Events

  1. Go to Alert Channels in Vigilmon.
  2. Add your team's Slack or email channel.
  3. On the heartbeat monitor, set Consecutive missed pings before alert to 1 — one missed analysis is already a problem.
  4. On HTTP monitors, set Consecutive failures to 2 to tolerate brief restarts.

Use a maintenance window during major registry migrations:

curl -X POST https://vigilmon.online/api/maintenance \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{"monitor_id": "abc123", "duration_minutes": 60}'

Summary

| Monitor | Target | What It Catches | |---|---|---| | Cron heartbeat | CI Dive analysis step | Dive not running on builds | | HTTP health | Results dashboard | Report aggregation service down | | HTTP health | /api/dive/health | No analyses in 24 hours | | TCP | Docker daemon | Docker socket unreachable |

Dive is most valuable when it runs on every build and teams can see trends. Vigilmon ensures the Dive integration never silently breaks — so image efficiency stays a first-class concern, not an afterthought discovered when production image pulls start timing out.

Monitor your app with Vigilmon

Free plan — 5 monitors, no credit card required. Up and running in 60 seconds.

Start free →