docker/compose · error

building from STDIN is not supported

Error message

building from STDIN is not supported

What it means

doBuildClassic calls build.DetectContextType on the resolved build context; when the context string is `-` (ContextTypeStdin) the classic builder cannot proceed because this code path builds a tar archive from a directory and has no way to consume a Dockerfile/context piped on stdin. Only BuildKit supports stdin contexts (it base64-encodes the Dockerfile into the API request).

Source

Thrown at pkg/compose/build_classic.go:166

	if service.Build.Labels == nil {
		service.Build.Labels = make(map[string]string)
	}
	service.Build.Labels[api.ImageBuilderLabel] = "classic"

	dockerfileName := dockerFilePath(service.Build.Context, service.Build.Dockerfile)
	specifiedContext := service.Build.Context
	progBuff := s.stdout()
	buildBuff := s.stdout()

	contextType, err := build.DetectContextType(specifiedContext)
	if err != nil {
		return "", err
	}

	switch contextType {
	case build.ContextTypeStdin:
		return "", fmt.Errorf("building from STDIN is not supported")
	case build.ContextTypeLocal:
		contextDir, relDockerfile, err = build.GetContextFromLocalDir(specifiedContext, dockerfileName)
		if err != nil {
			return "", fmt.Errorf("unable to prepare context: %w", err)
		}
		if strings.HasPrefix(relDockerfile, ".."+string(filepath.Separator)) {
			// Dockerfile is outside build-context; read the Dockerfile and pass it as dockerfileCtx
			dockerfileCtx, err = os.Open(dockerfileName)
			if err != nil {
				return "", fmt.Errorf("unable to open Dockerfile: %w", err)
			}
			defer dockerfileCtx.Close() //nolint:errcheck
		}
	case build.ContextTypeGit:
		var tempDir string
		tempDir, relDockerfile, err = build.GetContextFromGitURL(specifiedContext, dockerfileName)
		if err != nil {
			return "", fmt.Errorf("unable to prepare context: %w", err)

View on GitHub (pinned to ddc4b044b6)

Solutions

  1. Set DOCKER_BUILDKIT=1 so the BuildKit path handles stdin contexts
  2. Prefer a concrete context directory in the Compose file (e.g. `context: .`) instead of '-'
  3. Check the interpolated value of the context variable — an empty var defaulting to '-' is usually a configuration mistake

Example fix

# before
services:
  app:
    build:
      context: "${BUILD_CONTEXT:--}"

# after
services:
  app:
    build:
      context: "${BUILD_CONTEXT:-.}"
Defensive patterns

Strategy: validation

Validate before calling

ctx := strings.TrimSpace(svc.Build.Context)
if ctx == "-" {
    return fmt.Errorf("service %s: stdin context requires DOCKER_BUILDKIT=1", svc.Name)
}

Prevention

When it happens

Trigger: A Compose file (or interpolated value) that sets the service build context to `-`, e.g. `context: -`, combined with the classic builder path; commonly from `docker compose build -f-` style stdin usage or templated context fields resolving to '-'.

Common situations: Piping generated Compose files via stdin with env interpolation making the context '-'; scripts that reuse `docker build -` idioms inside Compose; YAML interpolation bugs where a variable holding the context is empty and a fallback '-' is used.

Related errors


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