# Where to Find the Source Code for Dive's Docker Image Resolver

> Discover where Dive's Docker image resolver source code resides. Find the core Resolver interface and Docker Engine implementations in the wagoodman/dive repository.

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

---

**The source code for Dive's Docker image resolver is located in the `dive/image/docker` package, with the core `Resolver` interface defined in [`dive/image/resolver.go`](https://github.com/wagoodman/dive/blob/main/dive/image/resolver.go) and concrete implementations handling Docker Engine and tar archive sources.**

Dive, the container image exploration tool maintained in the `wagoodman/dive` repository, abstracts image fetching behind a pluggable **Resolver** interface. If you need to extend Dive's image-loading capabilities or reuse its Docker integration in your own Go projects, you'll find the relevant source code organized into clear interface definitions and protocol-specific implementations.

## Core Interface: The Resolver Contract

The foundation of Dive's image resolution system lives in [`dive/image/resolver.go`](https://github.com/wagoodman/dive/blob/main/dive/image/resolver.go). This file defines the `Resolver` interface that all image sources—including Docker—must implement.

According to the `wagoodman/dive` source code, the interface requires four key capabilities:

```go
type Resolver interface {
    Name() string
    Fetch(ctx context.Context, id string) (*Image, error)
    Build(ctx context.Context, options []string) (*Image, error)
    ContentReader
}

type ContentReader interface {
    Extract(ctx context.Context, id string, layer string, path string) error
}

```

Any struct implementing these methods can serve as a valid image resolver, allowing Dive to support Docker Engine, Docker archives, Podman, and other container runtimes through the same abstraction.

## Docker-Specific Implementations

The Docker-specific resolvers reside in the `dive/image/docker/` directory. Dive provides two distinct resolvers for handling Docker images depending on their source location.

### Engine Resolver ([`engine_resolver.go`](https://github.com/wagoodman/dive/blob/main/engine_resolver.go))

The **Engine resolver** handles live Docker daemon interactions. Located in [`dive/image/docker/engine_resolver.go`](https://github.com/wagoodman/dive/blob/main/dive/image/docker/engine_resolver.go), this implementation connects to a running Docker Engine to pull, build, or save images.

Key functions in this file include:

- **`determineDockerHost()`** – Discovers the correct Docker host endpoint from environment variables or context
- **`fetchArchive()`** – Orchestrates the image save operation using `dockerClient.ImageSave()` to stream layers as a tar archive
- **`Fetch()`** – Checks if the image exists locally via `dockerClient.ImageInspect()`, pulls it if missing, then converts the Docker image stream into Dive's internal `Image` representation via `NewImageArchive()`

### Archive Resolver ([`archive_resolver.go`](https://github.com/wagoodman/dive/blob/main/archive_resolver.go))

The **Archive resolver** loads images from local tar files created by `docker save`. Found in [`dive/image/docker/archive_resolver.go`](https://github.com/wagoodman/dive/blob/main/dive/image/docker/archive_resolver.go), this resolver implements the same `Resolver` interface but works with static files rather than live daemons.

This resolver simply opens the specified tar path using `os.Open()` and passes the file handle to `NewImageArchive()`, which parses the Docker archive format into Dive's layer model.

## How Dive Selects the Right Resolver

Dive determines which concrete resolver to instantiate through a factory pattern defined in [`dive/get_image_resolver.go`](https://github.com/wagoodman/dive/blob/main/dive/get_image_resolver.go).

The selection process follows three steps:

1. **Source Parsing** – The `DeriveImageSource()` function parses URI strings (e.g., `docker://nginx:latest`) and maps them to an `ImageSource` enum value (`SourceDockerEngine`, `SourceDockerArchive`, etc.)

2. **Factory Dispatch** – `GetImageResolver()` returns the appropriate implementation based on the source type:

```go
func GetImageResolver(r ImageSource) (image.Resolver, error) {
    switch r {
    case SourceDockerEngine:
        return docker.NewResolverFromEngine(), nil
    case SourceDockerArchive:
        return docker.NewResolverFromArchive(), nil
    // … Podman, etc.
    }
    return nil, fmt.Errorf("unable to determine image resolver")
}

```

3. **Execution** – The returned resolver's `Fetch()` method handles the actual image acquisition, whether that means querying the Docker daemon or reading from disk.

## Programmatic Usage Examples

You can import and use Dive's resolvers directly in your own Go applications to leverage its Docker integration.

### Resolving from Docker Engine

```go
package main

import (
	"context"
	"log"

	"github.com/wagoodman/dive/dive"
	"github.com/wagoodman/dive/dive/image"
)

func main() {
	// Parse the source string the same way Dive's CLI does.
	src, imgRef := dive.DeriveImageSource("docker://nginx:latest")
	if src != dive.SourceDockerEngine {
		log.Fatalf("unexpected source: %v", src)
	}

	// Obtain the concrete resolver.
	resolver, err := dive.GetImageResolver(src)
	if err != nil {
		log.Fatalf("resolver error: %v", err)
	}

	// Fetch the image (pulls if needed).
	img, err := resolver.Fetch(context.Background(), imgRef)
	if err != nil {
		log.Fatalf("fetch error: %v", err)
	}

	// `img` now holds Dive's internal representation.
	log.Printf("Image %s has %d layers", img.ID, len(img.Layers))
}

```

### Loading from a Tar Archive

```go
resolver, _ := dive.GetImageResolver(dive.SourceDockerArchive)
img, err := resolver.Fetch(context.Background(), "/path/to/nginx.tar")
if err != nil {
    // handle error
}
log.Printf("Loaded archive image %s with %d layers", img.ID, len(img.Layers))

```

### Extracting Files from Layers

Use the `ContentReader` interface to pull specific files from image layers without loading the entire filesystem:

```go
resolver, _ := dive.GetImageResolver(dive.SourceDockerEngine)
err := resolver.Extract(context.Background(), "nginx:latest", "layerID", "/etc/nginx/nginx.conf")
if err != nil {
    // handle error
}

```

## Summary

- The **core `Resolver` interface** is defined in [`dive/image/resolver.go`](https://github.com/wagoodman/dive/blob/main/dive/image/resolver.go), requiring `Name()`, `Fetch()`, `Build()`, and `Extract()` methods
- **Docker Engine resolution** is implemented in [`dive/image/docker/engine_resolver.go`](https://github.com/wagoodman/dive/blob/main/dive/image/docker/engine_resolver.go), handling live daemon interactions, host detection, and image pulling
- **Docker Archive resolution** lives in [`dive/image/docker/archive_resolver.go`](https://github.com/wagoodman/dive/blob/main/dive/image/docker/archive_resolver.go) for loading `docker save` tar files
- The **factory function** `GetImageResolver()` in [`dive/get_image_resolver.go`](https://github.com/wagoodman/dive/blob/main/dive/get_image_resolver.go) maps source strings to concrete implementations via `DeriveImageSource()`

## Frequently Asked Questions

### What file contains the Resolver interface definition?

The `Resolver` interface and the embedded `ContentReader` interface are both defined in [`dive/image/resolver.go`](https://github.com/wagoodman/dive/blob/main/dive/image/resolver.go). This file establishes the contract that all image resolution implementations—including Docker, Podman, and containerd—must satisfy to integrate with Dive's analysis engine.

### How does Dive choose between the engine and archive resolvers?

Dive uses the `DeriveImageSource()` function in [`dive/get_image_resolver.go`](https://github.com/wagoodman/dive/blob/main/dive/get_image_resolver.go) to parse the input string. If the string starts with `docker://` or lacks a protocol prefix (defaulting to Docker), it returns `SourceDockerEngine`. If the path points to a `.tar` file, it returns `SourceDockerArchive`. The `GetImageResolver()` factory then instantiates the appropriate struct from the `dive/image/docker` package.

### Can I use Dive's resolvers in my own Go code?

Yes. Import `github.com/wagoodman/dive/dive` and `github.com/wagoodman/dive/dive/image` into your project. Use `dive.DeriveImageSource()` to parse image references, then call `dive.GetImageResolver()` to obtain a resolver implementing the `image.Resolver` interface. This allows you to programmatically fetch images or extract files from specific layers without invoking the Dive CLI directly.

### Where does the engine resolver handle Docker host detection?

Docker host detection occurs in [`dive/image/docker/engine_resolver.go`](https://github.com/wagoodman/dive/blob/main/dive/image/docker/engine_resolver.go) within the `determineDockerHost()` helper function. This function inspects environment variables like `DOCKER_HOST` and platform-specific contexts to determine the correct API endpoint before constructing the Docker client used for `ImageInspect` and `ImageSave` operations.