Container images often carry hidden megabytes of leftover build artifacts, cache files, and unlinked dependencies. Even worse, developers frequently expose sensitive credentials in intermediate layers without realizing that deleting a file in a later step does not purge it from the underlying image. Dive is an open-source terminal inspection tool built to explore container layers, detect wasted disk space, and discover exposed secrets.
You can track release binaries and source code directly on the official Dive GitHub repository. It parses Docker and OCI images, providing an interactive dual-pane view that separates filesystem layers from aggregated directory trees.
Docker and Podman rely on copy-on-write (CoW) union filesystems like OverlayFS. Each line in a Dockerfile that modifies files creates a distinct, immutable tar archive layer.
Running a command like RUN apt-get update && rm -rf /var/lib/apt/lists/* inside two separate RUN instructions creates a common gotcha. The deleted files remain permanently stored inside the previous layer tarball. Security tools like Gitleaks catch committed secrets in Git trees, but Dive catches credentials accidentally cached across intermediate image layers.
Installing Dive on Linux takes only a single package command. Pre-built deb and rpm packages support x86_64 and ARM architectures.
# Install on Debian and Ubuntu wget https://github.com/wagoodman/dive/releases/download/v0.12.0/dive_0.12.0_linux_amd64.deb sudo apt install ./dive_0.12.0_linux_amd64.deb # Install on RHEL and CentOS sudo rpm -i https://github.com/wagoodman/dive/releases/download/v0.12.0/dive_0.12.0_linux_amd64.rpm # Install on Arch Linux via AUR yay -S dive # Install on macOS via Homebrew brew install dive
You can also run Dive directly as a container without installing native binaries. Pass the local Docker socket as a volume so Dive can communicate with your container runtime.
docker run --rm -it \ -v /var/run/docker.sock:/var/run/docker.sock \ wagoodman/dive:latest <image-name>
Launching an inspection requires only the image name or digest. Dive loads the image manifest, unpacks the layer tarballs, and renders the dual-pane terminal interface.
# Inspect an existing local or remote image dive my-app:latest # Build and analyze immediately in one command dive build -t my-app:latest .
The left pane lists every layer with its exact build instruction, virtual size, and SHA256 digest. The right pane displays the complete container filesystem tree for the highlighted layer. File paths render with specific color markers: green indicates added files, yellow indicates modifications, and red flags deleted files.
| Key Binding | Action | View Scope |
|---|---|---|
Tab | Switch focus between layer list and filetree | Global |
Ctrl + F | Filter files by name or regular expression | Filetree View |
Ctrl + A | Toggle aggregated changes across all layers | Layer View |
Ctrl + L | Show changes introduced strictly in current layer | Layer View |
Space | Expand or collapse current directory branch | Filetree View |
Ctrl + R | Filter to display deleted files only | Filetree View |
Navigating the layer list with Ctrl + L lets you confirm whether temporary compiler binaries were correctly scrubbed. It operates far faster than extracting tar archives manually using a standard Linux shell.
Interactive terminal inspection works well for local debugging, but pipeline automation prevents oversized images from hitting production registries. Running Dive with CI=true bypasses the terminal UI and outputs an automated audit score.
Define a .dive-ci YAML configuration file at the root of your project repository. This file specifies strict efficiency boundaries and maximum allowed waste limits.
rules: # Fail pipeline if image efficiency drops below 95% lowestEfficiency: 0.95 # Fail pipeline if total wasted bytes exceed 20MB highestWastedBytes: 20MB # Fail if user-created layers waste more than 15% of space highestUserWastedPercent: 0.15
Execute the automated validation step inside your GitHub Actions or GitLab CI runner.
CI=true dive my-app:production --source docker
Dive evaluates the image against your rules and exits with status code 0 on pass or status code 1 on failure. Broken builds prevent bloated containers from reaching container registries.
Dive supports multiple container runtimes through the --source flag. You are not locked into the default Docker daemon.
# Analyze an image managed by Podman dive my-container:latest --source podman # Analyze an air-gapped exported image tarball dive /backups/app-image.tar --source docker-archive
Analyzing exported tarballs allows security audit teams to evaluate third-party appliance images in isolated sandbox machines without starting a local container daemon.