How to Integrate Dive into CI/CD Pipelines for Automated Image Analysis

Set CI=true or pass the --ci flag to enable non-interactive mode, configure thresholds in a .dive-ci file, and enforce Docker image efficiency policies that fail the build when any rule is violated.

Integrating Dive into CI/CD pipelines allows development teams to automatically validate Docker and OCI image efficiency during the build process. The open-source tool wagoodman/dive analyzes image layers and returns a non-zero exit code when configured efficiency rules are breached, preventing bloated containers from reaching production.

Understanding Dive's CI Mode Architecture

Dive's CI functionality is implemented in cmd/dive/cli/internal/options/ci.go, where the application detects automation environments through the truthy(os.Getenv("CI")) function or the explicit --ci flag. When CI mode is detected, the tool suppresses the interactive TUI and prepares for automated evaluation.

The root command in cmd/dive/cli/internal/command/root.go checks opts.CI.Enabled to determine whether to invoke the standard interactive viewer or route execution to the CI evaluator. When CI mode is active, Dive loads the configuration and delegates analysis to the evaluator defined in cmd/dive/cli/internal/command/ci/evaluator.go, which compares image metrics against defined thresholds and returns an error on violation, resulting in exit code 1.

Configuring CI Rules with .dive-ci

Efficiency policies are defined in a YAML configuration file parsed by the PostLoad() method in cmd/dive/cli/internal/options/ci.go. The default filename is .dive-ci, though you can specify an alternative path using the --ci-config flag.

The rule schema is defined in cmd/dive/cli/internal/options/ci_rules.go and supports three threshold metrics:

  • lowestEfficiency: Minimum acceptable ratio of efficient bytes to total bytes (0.0 to 1.0)
  • highestWastedBytes: Maximum allowable wasted space (e.g., 20MB)
  • highestUserWastedPercent: Maximum percentage of user-added layers that are wasted (0.0 to 1.0)

Create a .dive-ci file at your repository root:

rules:
  lowestEfficiency: 0.95          # Fail if efficiency drops below 95%

  highestWastedBytes: 20MB        # Fail if wasted space exceeds 20 MiB

  highestUserWastedPercent: 0.20  # Fail if >20% of user layers are wasted

Pipeline Integration Examples

GitHub Actions

In cmd/dive/cli/internal/command/root.go, the application checks for CI mode before dispatching. Use the following workflow to build an image and validate it with Dive:

name: Docker Image CI

on:
  push:
    branches: [main]

jobs:
  build-and-analyze:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Build Docker image
        run: docker build -t myapp:ci .

      - name: Analyze image efficiency with Dive
        env:
          CI: true
        run: |
          curl -sSfL https://github.com/wagoodman/dive/releases/download/v0.12.0/dive_0.12.0_linux_amd64.deb -o dive.deb
          sudo dpkg -i dive.deb
          dive myapp:ci

GitLab CI

Set the CI environment variable in your job definition to trigger the evaluator logic in cmd/dive/cli/internal/command/ci/evaluator.go:

stages:
  - build
  - validate

docker-build:
  stage: build
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker build -t myapp:ci .

dive-analysis:
  stage: validate
  image: ubuntu:latest
  variables:
    CI: "true"
  before_script:
    - apt-get update && apt-get install -y curl
    - curl -sSfL https://github.com/wagoodman/dive/releases/download/v0.12.0/dive_0.12.0_linux_amd64.deb -o dive.deb
    - dpkg -i dive.deb || apt-get install -f -y
  script:
    - dive myapp:ci
  allow_failure: false

Using dive build for On-the-Fly Analysis

Dive supports analyzing images built during the pipeline step without requiring a separate build command. The dive build command constructs the image and immediately evaluates it against your CI rules:

CI=true dive build -t myapp:ci .

This approach is particularly effective in minimal CI runners where passing image IDs between steps is cumbersome.

Summary

  • Enable CI mode by setting the environment variable CI=true or passing the --ci flag to suppress the interactive interface.
  • Configure thresholds in a .dive-ci YAML file (or custom path via --ci-config) using lowestEfficiency, highestWastedBytes, and highestUserWastedPercent rules.
  • Fail pipelines automatically when Dive's evaluator in cmd/dive/cli/internal/command/ci/evaluator.go detects violations, returning exit code 1.
  • Analyze existing or new images using dive <image> or dive build respectively.

Frequently Asked Questions

What exit code does Dive return when CI checks fail?

Dive returns exit code 1 when any configured CI rule is violated. This non-zero status automatically triggers pipeline failure in GitHub Actions, GitLab CI, and other automation platforms without requiring additional scripting logic.

Can I use a custom configuration file name instead of .dive-ci?

Yes. While Dive defaults to loading .dive-ci from the working directory via the PostLoad() method in cmd/dive/cli/internal/options/ci.go, you can specify an alternative file path using the --ci-config flag, such as dive --ci-config ./config/dive-policy.yml myapp:ci.

Does Dive support analyzing images built during the pipeline?

Yes. Use the dive build command followed by standard Docker build arguments. When CI=true is set, Dive builds the image and immediately evaluates it against your CI rules without requiring intermediate image tagging or artifact passing between steps.

How does Dive detect CI mode automatically?

The cmd/dive/cli/internal/options/ci.go file implements truthy(os.Getenv("CI")) to check for common CI environment variables. Alternatively, you can explicitly pass the --ci flag to force non-interactive mode regardless of environment detection.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →