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

> Integrate Dive into your CI/CD pipelines for automated Docker image analysis. Enforce efficiency policies and fail builds on violations with non-interactive mode and threshold configuration.

- Repository: [Alex Goodman/dive](https://github.com/wagoodman/dive)
- Tags: how-to-guide
- Published: 2026-03-07

---

**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`](https://github.com/wagoodman/dive/blob/main/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`](https://github.com/wagoodman/dive/blob/main/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`](https://github.com/wagoodman/dive/blob/main/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`](https://github.com/wagoodman/dive/blob/main/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`](https://github.com/wagoodman/dive/blob/main/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:

```yaml
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`](https://github.com/wagoodman/dive/blob/main/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:

```yaml
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`](https://github.com/wagoodman/dive/blob/main/cmd/dive/cli/internal/command/ci/evaluator.go):

```yaml
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:

```bash
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`](https://github.com/wagoodman/dive/blob/main/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`](https://github.com/wagoodman/dive/blob/main/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`](https://github.com/wagoodman/dive/blob/main/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.