Dive Tool Usage Patterns and Examples: A Complete Guide
The Dive CLI supports interactive layer-by-layer Docker image inspection, CI-driven efficiency enforcement, and programmatic analysis through a unified pipeline involving image resolution, file-tree comparison, and configurable UI rendering.
The Dive tool from the wagoodman/dive repository is a Go-based CLI utility that dissects Docker and OCI images to reveal wasted space and filesystem changes across layers. Whether you are optimizing container builds or enforcing size budgets in pipelines, understanding these Dive tool usage patterns and examples helps you integrate layer analysis into development workflows.
Interactive Image Inspection Patterns
Analyzing Local Docker Images
The most common pattern involves inspecting existing images directly from the Docker daemon. When you run dive nginx:latest, the tool invokes the engine resolver defined in dive/image/docker/engine_resolver.go to fetch image metadata and layer tarballs. Each layer is parsed by the file-tree comparer in dive/filetree/comparer.go, which tracks added, removed, and modified files to render the interactive terminal interface defined in cmd/dive/cli/internal/ui/v1/app/app.go.
dive alpine:3.18
Working with Docker Archives and Alternative Sources
For environments without a running Docker daemon, Dive supports archive-based resolution. The archive resolver in dive/image/docker/archive_resolver.go loads tarballs directly, while Podman users can specify --source podman to utilize the resolver implemented in dive/image/podman/resolver.go.
# Analyze a saved tarball without Docker daemon
dive myimage.tar --source docker-archive
# Use Podman as the image source (Linux/macOS)
dive myimage --source podman
Build-and-Inspect Workflows
The build command integrates container construction with immediate analysis. Implemented in cmd/dive/cli/internal/command/build.go, this pattern executes Docker or Podman builds, captures the resulting image ID, and automatically passes it to the analysis pipeline. This eliminates manual intermediate steps when optimizing Dockerfiles.
dive build -t myapp .
CI/CD Integration and Efficiency Enforcement
In automated pipelines, Dive operates in headless mode when the CI=true environment variable is set. The UI is bypassed, and the tool evaluates rules defined in a .dive-ci configuration file, exiting with code 1 if thresholds for efficiency or wasted bytes are violated. This pattern leverages the same core analysis pipeline as interactive mode but disables rendering via cmd/dive/cli/internal/ui/v1/app/app.go.
cat > .dive-ci <<EOF
rules:
highestWastedBytes: 20MB
lowestEfficiency: 0.95
EOF
CI=true dive myimage --ci-config .dive-ci
Programmatic Usage and Custom Tooling
Advanced users can embed Dive's analysis engine into Go applications. By importing the internal packages, you can instantiate resolvers and run analyses without the terminal UI. The following example demonstrates creating a Docker resolver via adapter.NewResolver, loading configuration, and executing a headless analysis.
package main
import (
"context"
"fmt"
"os"
"github.com/wagoodman/dive/cmd/dive/cli/internal/command/adapter"
"github.com/wagoodman/dive/internal/bus"
"github.com/wagoodman/dive/internal/config"
"github.com/wagoodman/dive/internal/ui"
)
func main() {
// Resolve the image using the Docker engine resolver
resolver, err := adapter.NewResolver("docker")
if err != nil {
panic(err)
}
imageRef := "nginx:latest"
image, err := resolver.Resolve(context.Background(), imageRef)
if err != nil {
panic(err)
}
// Configure for CI mode (headless)
cfg := config.Default()
cfg.CI = true
if path := os.Getenv("DIVE_CI_CONFIG"); path != "" {
if err := cfg.Load(path); err != nil {
panic(err)
}
}
// Run analysis without UI
analysis := ui.NewAnalysis(cfg, bus.New())
if err := analysis.Run(context.Background(), image); err != nil {
panic(err)
}
if analysis.HasFailures() {
os.Exit(1)
}
fmt.Println("Image passes all Dive CI checks")
}
Configuration and Customization
Dive merges user-provided YAML configurations with defaults to modify behavior. You can override key bindings, adjust pane widths, or hide specific diff types using the --config flag. The configuration parsing logic resides in the config package and cmd/dive/cli/internal/ui/v1/config.go, allowing customization of the terminal interface without recompiling.
dive myimage --config ./custom-dive.yaml
Summary
- Layer-by-layer inspection via
dive/image/resolver.goanddive/filetree/comparer.goforms the core of every Dive workflow. - Interactive analysis uses the terminal UI in
cmd/dive/cli/internal/ui/v1/app/app.goto visualize filesystem changes and efficiency scores. - CI enforcement runs headless with
CI=true, evaluating.dive-cirules and returning non-zero exit codes on failure. - Build integration through
dive buildcombines construction and analysis in a single command handled bycmd/dive/cli/internal/command/build.go. - Programmatic access allows embedding Dive's resolution and analysis pipeline into custom Go tooling via the
adapteranduipackages.
Frequently Asked Questions
How does Dive calculate image efficiency?
Dive calculates efficiency by identifying duplicated files across layers, orphaned deletions, and unreferenced data. The dive/filetree/comparer.go file builds cumulative file-trees for each layer to track these metrics, which the UI then renders as a percentage score based on wasted space analysis.
Can Dive analyze images without a Docker daemon?
Yes. Dive supports docker-archive sources for tarballs and podman as alternative engines. The dive/image/docker/archive_resolver.go handles tar archives, while dive/image/podman/resolver.go interfaces with Podman on Linux and macOS systems, making the tool viable for daemon-less CI environments.
What exit codes does Dive return in CI mode?
When running with CI=true, Dive exits with code 0 if all .dive-ci rules pass, and code 1 if any efficiency or wasted-space threshold is violated. This behavior is implemented in the analysis pipeline within cmd/dive/cli/internal/ui/v1/app/app.go, ensuring reliable pipeline integration.
How do I customize key bindings in the Dive UI?
Key bindings and pane layouts are controlled via YAML configuration files. Dive merges custom configurations specified with --config against defaults defined in the config package and cmd/dive/cli/internal/ui/v1/config.go, allowing you to remap controls or hide specific diff views like "removed" entries.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →