Skip to main content
Enforces consistent indentation for Dockerfile build stages.
PropertyValue
SeverityStyle
CategoryStyle
DefaultOff (experimental)
Auto-fixYes (safe)

Description

Enforces consistent indentation to visually separate build stages in multi-stage Dockerfiles. This rule always uses tabs for indentation. Behavior depends on the number of stages:
  • Multi-stage (2+ FROM instructions): Commands within each stage must be indented with 1 tab. FROM lines remain at column 0.
  • Single-stage (1 FROM instruction): All indentation is removed — tabs, spaces, or any mix. Since there is no stage structure to communicate, indenting commands adds noise. The auto-fix strips all leading whitespace from every instruction.

Why tabs only?

Docker heredoc syntax (<<-) strips leading tabs from body lines. Spaces have no equivalent shell whitespace treatment — using them for indentation would corrupt heredoc content when <<- is applied. Because this rule must convert << to <<- when adding indentation to heredoc instructions, only tabs produce correct results.
FROM alpine:3.20
	COPY <<-EOF /etc/config
		key=value
		other=setting
	EOF
With spaces, <<- cannot strip indentation, so the content would retain unwanted leading whitespace.

Multi-stage (indentation required)

FROM golang:1.23 AS builder
	WORKDIR /src
	COPY . .
	RUN go build -o /app

FROM alpine:3.20
	COPY --from=builder /app /usr/local/bin/app
	ENTRYPOINT ["app"]

Single-stage (no indentation)

FROM alpine:3.20
RUN apk add --no-cache curl
COPY . /app
CMD ["./app"]

Examples

Bad (multi-stage without indentation)

FROM golang:1.23 AS builder
WORKDIR /src
RUN go build -o /app
FROM alpine:3.20
COPY --from=builder /app /app

Good (multi-stage with tab indentation)

FROM golang:1.23 AS builder
	WORKDIR /src
	RUN go build -o /app
FROM alpine:3.20
	COPY --from=builder /app /app

Bad (single-stage with indentation)

In a single-stage Dockerfile, indentation is unnecessary and will be removed by --fix:
# Before (violation: unexpected indentation)
FROM alpine:3.20
	RUN apk add curl
	COPY . /app

# After --fix (indentation removed)
FROM alpine:3.20
RUN apk add curl
COPY . /app

Configuration

Enable the rule (no configurable options — tabs are always used):
[rules.tally.consistent-indentation]
severity = "style"

Auto-fix

This rule provides safe auto-fixes that adjust indentation:
  • Multi-stage: Adds 1 tab indentation to commands within stages
  • Single-stage: Removes all leading whitespace (tabs and spaces) from commands
  • Style correction: Replaces wrong indent characters (e.g., spaces to tabs)
  • Heredoc <<- conversion: When tab indentation is applied to a heredoc instruction (RUN <<EOF, COPY <<EOF), the fix converts << to <<- so that BuildKit strips the leading tabs from the heredoc body
tally lint --fix Dockerfile