Skip to main content
Runtime-configuration instructions should appear at the end of each output stage in canonical order.
PropertyValue
SeverityStyle
CategoryStyle
DefaultEnabled
Auto-fixYes (safe)

Description

Dockerfiles should end each output stage with runtime-configuration instructions in a canonical order: STOPSIGNAL, HEALTHCHECK, ENTRYPOINT, CMD. These epilogue instructions configure how the container runs rather than how the image is built, and placing them at the end of the stage makes the Dockerfile easier to read and maintain. This rule checks two conditions for each applicable stage:
  1. Position: All epilogue instructions must appear at the end of the stage (no build instructions like RUN, COPY, ENV after them)
  2. Order: Among the epilogue instructions, they must appear in canonical order
Applicable stages: The final stage and any stage with no dependents (not referenced by COPY --from, FROM, or RUN --mount=from). Intermediate builder stages are skipped since they typically don’t use epilogue instructions.

Examples

Bad

FROM alpine:3.20
CMD ["/app", "serve"]
RUN apk add --no-cache ca-certificates
ENTRYPOINT ["/app"]
CMD appears before RUN (position violation), and CMD comes before ENTRYPOINT (order violation).

Good

FROM alpine:3.20
RUN apk add --no-cache ca-certificates
ENTRYPOINT ["/app"]
CMD ["serve"]
All build instructions come first, then epilogue instructions in canonical order.

Multi-stage (builder skipped)

FROM golang:1.21 AS builder
RUN go build -o /app
# No violation here - builder stage is skipped

FROM alpine:3.20
COPY --from=builder /app /app
ENTRYPOINT ["/app"]
CMD ["serve"]

Auto-fix

This rule provides a safe auto-fix that moves epilogue instructions to the end of the stage in canonical order:
tally lint --fix Dockerfile
The fix:
  • Removes each epilogue instruction from its current position
  • Inserts all epilogue instructions at the end of the stage in canonical order
  • Preserves preceding comments and continuation lines
When duplicate epilogue instructions of the same type exist (e.g., two CMD instructions), the fix is skipped for safety. The MultipleInstructionsDisallowed rule handles duplicate removal.

Cross-rule interactions

RuleInteraction
tally/newline-between-instructionsRuns after this rule’s fix (priority 200 vs 175). Normalizes blank lines between the reordered epilogue instructions. The combined result is stable.
buildkit/MultipleInstructionsDisallowedRuns before (sync fix). Removes duplicate CMD/ENTRYPOINT/HEALTHCHECK. If duplicates remain (rule disabled), this rule skips the fix for safety.