docker/compose · error

interactive run is not supported in dry-run mode

Error message

interactive run is not supported in dry-run mode

What it means

In --dry-run mode Compose swaps the Docker client for DryRunClient, which simulates mutations but cannot simulate an interactive TTY attach. Any code path that would attach the terminal to a container (ContainerAttach, used by run -it / up with interactive allocation) is hard-blocked so dry-run output stays pure and deterministic.

Source

Thrown at pkg/dryrun/dryrunclient.go:93

	}
	return &DryRunClient{
		apiClient:  apiClient,
		containers: []containerType.Summary{},
		execs:      sync.Map{},
		resolver:   imagetools.New(configFile),
	}, nil
}

func getCallingFunction() string {
	pc, _, _, _ := runtime.Caller(2)
	fullName := runtime.FuncForPC(pc).Name()
	return fullName[strings.LastIndex(fullName, ".")+1:]
}

// All methods and functions which need to be overridden for dry run.

func (d *DryRunClient) ContainerAttach(ctx context.Context, container string, options client.ContainerAttachOptions) (client.ContainerAttachResult, error) {
	return client.ContainerAttachResult{}, errors.New("interactive run is not supported in dry-run mode")
}

func (d *DryRunClient) ContainerCreate(ctx context.Context, options client.ContainerCreateOptions) (client.ContainerCreateResult, error) {
	d.containers = append(d.containers, containerType.Summary{
		ID:     options.Name,
		Names:  []string{options.Name},
		Labels: options.Config.Labels,
		HostConfig: struct {
			NetworkMode string            `json:",omitempty"`
			Annotations map[string]string `json:",omitempty"`
		}{},
	})
	return client.ContainerCreateResult{ID: options.Name}, nil
}

func (d *DryRunClient) ContainerInspect(ctx context.Context, container string, options client.ContainerInspectOptions) (client.ContainerInspectResult, error) {
	containerJSON, err := d.apiClient.ContainerInspect(ctx, container, options)
	if err != nil {

View on GitHub (pinned to ddc4b044b6)

Solutions

  1. Drop the interactive flags for the dry-run invocation: `docker compose run --dry-run <svc>` (no -i/-t)
  2. Add `-T` (disable pseudo-TTY) when piping: `docker compose run --dry-run -T svc cmd`
  3. If you must test interactively, run without --dry-run against a throwaway project

Example fix

# before
docker compose run --dry-run -it web sh
# after
docker compose run --dry-run -T web sh
Defensive patterns

Strategy: validation

Validate before calling

# strip TTY flags when dry-running in scripts
run_compose() {
  if [ "$1" = "--dry-run" ]; then shift; docker compose --dry-run run -T "$@"; else docker compose run "$@"; fi
}

Prevention

When it happens

Trigger: `docker compose run --dry-run -it <svc>` or any API path that calls ContainerAttach while the dry-run client is active.

Common situations: CI or scripted dry-run validation of commands that were copied from interactive usage; testing `docker compose run` pipelines that still carry -it flags.

Related errors


AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15). Data as JSON: /api/errors/62ba9108c06f6e09. Report an issue: GitHub.