> ## Documentation Index
> Fetch the complete documentation index at: https://tally.wharflab.com/llms.txt
> Use this file to discover all available pages before exploring further.

# BuildKit rules

> tally supports all 22 BuildKit checks, including reimplementations of build-time checks as pure static analysis.

<Note>
  tally supports **22/22** BuildKit checks. 5 are captured directly from BuildKit's parser; 17 are reimplemented as static rules so they work without running Docker/BuildKit.
</Note>

BuildKit checks come from Docker's official [build checks reference](https://docs.docker.com/reference/build-checks/). tally integrates them in two
ways:

* **Implemented by tally** — BuildKit normally runs these during LLB conversion (i.e., when actually building). tally reimplements them as pure static
  checks so they catch issues without a Docker daemon.
* **Captured from BuildKit parser** — These are emitted by BuildKit during Dockerfile parsing and forwarded directly to tally's diagnostic pipeline.

All 11 auto-fixable rules are marked with 🔧. Run `tally lint --fix` to apply safe fixes automatically.

***

## Implemented by tally

These 17 checks correspond to BuildKit's LLB-conversion checks. tally runs them statically, so you get full coverage without Docker or BuildKit
installed.

<AccordionGroup>
  <Accordion title="buildkit/ConsistentInstructionCasing 🔧 — Warning">
    All commands within the Dockerfile should use the same casing (either upper or lower).

    **Severity:** Warning (enabled by default) · **Auto-fixable:** Yes

    **Docker docs:** [consistent-instruction-casing](https://docs.docker.com/reference/build-checks/consistent-instruction-casing/)

    ```dockerfile theme={null}
    # Violation: mixed casing
    FROM alpine
    run apk add curl
    COPY . /app
    cmd ["./app"]
    ```
  </Accordion>

  <Accordion title="buildkit/CopyIgnoredFile — Warning">
    Attempting to COPY a file that is excluded by `.dockerignore`.

    **Severity:** Warning (enabled by default) · **Auto-fixable:** No

    **Docker docs:** [copy-ignored-file](https://docs.docker.com/reference/build-checks/copy-ignored-file/)

    ```dockerfile theme={null}
    # .dockerignore contains: *.log

    # Violation: copying a file excluded by .dockerignore
    COPY app.log /app/app.log
    ```
  </Accordion>

  <Accordion title="buildkit/DuplicateStageName — Error">
    Stage names should be unique.

    **Severity:** Error (enabled by default) · **Auto-fixable:** No

    **Docker docs:** [duplicate-stage-name](https://docs.docker.com/reference/build-checks/duplicate-stage-name/)

    ```dockerfile theme={null}
    # Violation: two stages share the name "builder"
    FROM alpine AS builder
    RUN echo "first"

    FROM ubuntu AS builder
    RUN echo "second"
    ```
  </Accordion>

  <Accordion title="buildkit/ExposeInvalidFormat — Warning">
    IP address and host-port mapping should not be used in EXPOSE. This will become an error in a future release.

    **Severity:** Warning (enabled by default) · **Auto-fixable:** No

    **Docker docs:** [expose-invalid-format](https://docs.docker.com/reference/build-checks/expose-invalid-format/)

    ```dockerfile theme={null}
    # Violation: host-port mapping in EXPOSE
    EXPOSE 0.0.0.0:8080
    ```
  </Accordion>

  <Accordion title="buildkit/ExposeProtoCasing 🔧 — Warning">
    Protocol in EXPOSE instruction should be lowercase.

    **Severity:** Warning (enabled by default) · **Auto-fixable:** Yes

    **Docker docs:** [expose-proto-casing](https://docs.docker.com/reference/build-checks/expose-proto-casing/)

    ```dockerfile theme={null}
    # Violation: protocol in uppercase
    EXPOSE 80/TCP
    EXPOSE 443/UDP
    ```
  </Accordion>

  <Accordion title="buildkit/FromPlatformFlagConstDisallowed — Off">
    `FROM --platform` flag should not use a constant value.

    **Severity:** Off by default · **Auto-fixable:** No

    **Docker docs:** [from-platform-flag-const-disallowed](https://docs.docker.com/reference/build-checks/from-platform-flag-const-disallowed/)

    ```dockerfile theme={null}
    # Violation: hardcoded platform instead of using build arg
    FROM --platform=linux/amd64 alpine
    ```
  </Accordion>

  <Accordion title="buildkit/InvalidBaseImagePlatform — Off">
    Base image platform does not match expected target platform.

    **Severity:** Off by default · **Auto-fixable:** No

    ```dockerfile theme={null}
    # Violation: explicit platform conflicts with the target platform
    FROM --platform=linux/arm64 node:20 AS builder
    ```
  </Accordion>

  <Accordion title="buildkit/InvalidDefaultArgInFrom — Error">
    Default value for a global ARG results in an empty or invalid base image name.

    **Severity:** Error (enabled by default) · **Auto-fixable:** No

    **Docker docs:** [invalid-default-arg-in-from](https://docs.docker.com/reference/build-checks/invalid-default-arg-in-from/)

    ```dockerfile theme={null}
    # Violation: ARG default is empty, making the image name invalid
    ARG BASE_IMAGE=""
    FROM ${BASE_IMAGE}
    ```
  </Accordion>

  <Accordion title="buildkit/JSONArgsRecommended 🔧 — Info">
    JSON arguments are recommended for ENTRYPOINT/CMD to prevent unintended behavior related to OS signals.

    **Severity:** Info (enabled by default) · **Auto-fixable:** Yes

    **Docker docs:** [json-args-recommended](https://docs.docker.com/reference/build-checks/json-args-recommended/)

    ```dockerfile theme={null}
    # Violation: shell form — PID 1 is /bin/sh, not the process
    ENTRYPOINT myapp --config /etc/myapp.conf
    CMD myapp
    ```
  </Accordion>

  <Accordion title="buildkit/LegacyKeyValueFormat 🔧 — Warning">
    Legacy key/value format with whitespace separator should not be used.

    **Severity:** Warning (enabled by default) · **Auto-fixable:** Yes

    **Docker docs:** [legacy-key-value-format](https://docs.docker.com/reference/build-checks/legacy-key-value-format/)

    ```dockerfile theme={null}
    # Violation: legacy whitespace-separated ENV and LABEL syntax
    ENV MY_VAR my_value
    LABEL maintainer John Doe
    ```
  </Accordion>

  <Accordion title="buildkit/MultipleInstructionsDisallowed 🔧 — Warning">
    Multiple instructions of the same type should not be used in the same stage.

    **Severity:** Warning (enabled by default) · **Auto-fixable:** Yes

    **Docker docs:** [multiple-instructions-disallowed](https://docs.docker.com/reference/build-checks/multiple-instructions-disallowed/)

    ```dockerfile theme={null}
    FROM alpine
    # Violation: two CMD instructions; only the last takes effect
    CMD ["echo", "first"]
    CMD ["echo", "second"]
    ```
  </Accordion>

  <Accordion title="buildkit/RedundantTargetPlatform — Warning">
    Setting `--platform` to the predefined `$TARGETPLATFORM` in FROM is redundant as it is the default behavior.

    **Severity:** Warning (enabled by default) · **Auto-fixable:** No

    **Docker docs:** [redundant-target-platform](https://docs.docker.com/reference/build-checks/redundant-target-platform/)

    ```dockerfile theme={null}
    # Violation: $TARGETPLATFORM is already the default
    FROM --platform=$TARGETPLATFORM alpine
    ```
  </Accordion>

  <Accordion title="buildkit/ReservedStageName — Error">
    Reserved words should not be used as stage names.

    **Severity:** Error (enabled by default) · **Auto-fixable:** No

    **Docker docs:** [reserved-stage-name](https://docs.docker.com/reference/build-checks/reserved-stage-name/)

    ```dockerfile theme={null}
    # Violation: "scratch" is a reserved stage name
    FROM alpine AS scratch
    RUN echo "building"
    ```
  </Accordion>

  <Accordion title="buildkit/SecretsUsedInArgOrEnv — Warning">
    Sensitive data should not be used in the ARG or ENV commands.

    **Severity:** Warning (enabled by default) · **Auto-fixable:** No

    **Docker docs:** [secrets-used-in-arg-or-env](https://docs.docker.com/reference/build-checks/secrets-used-in-arg-or-env/)

    ```dockerfile theme={null}
    # Violation: secret value baked into the image layer
    ARG AWS_SECRET_ACCESS_KEY
    ENV DATABASE_PASSWORD=supersecret
    ```
  </Accordion>

  <Accordion title="buildkit/UndefinedArgInFrom — Warning">
    FROM command must use declared ARGs.

    **Severity:** Warning (enabled by default) · **Auto-fixable:** No

    **Docker docs:** [undefined-arg-in-from](https://docs.docker.com/reference/build-checks/undefined-arg-in-from/)

    ```dockerfile theme={null}
    # Violation: IMAGE_TAG is not declared before use in FROM
    FROM alpine:${IMAGE_TAG}
    ```
  </Accordion>

  <Accordion title="buildkit/UndefinedVar — Warning">
    Variables should be defined before their use.

    **Severity:** Warning (enabled by default) · **Auto-fixable:** No

    **Docker docs:** [undefined-var](https://docs.docker.com/reference/build-checks/undefined-var/)

    ```dockerfile theme={null}
    FROM alpine
    # Violation: $APP_DIR was never defined with ARG or ENV
    COPY . $APP_DIR
    ```
  </Accordion>

  <Accordion title="buildkit/WorkdirRelativePath 🔧 — Warning">
    Relative WORKDIR without a prior absolute WORKDIR can have unexpected results if the base image changes.

    **Severity:** Warning (enabled by default) · **Auto-fixable:** Yes

    **Docker docs:** [workdir-relative-path](https://docs.docker.com/reference/build-checks/workdir-relative-path/)

    ```dockerfile theme={null}
    FROM alpine
    # Violation: relative path depends on the base image's CWD
    WORKDIR app
    ```
  </Accordion>
</AccordionGroup>

***

## Captured from BuildKit parser

These 5 checks are emitted by BuildKit during Dockerfile parsing. tally captures them directly and includes them in its diagnostic output alongside
statically implemented rules.

<AccordionGroup>
  <Accordion title="buildkit/FromAsCasing 🔧 — Warning">
    The `as` keyword should match the case of the `from` keyword.

    **Severity:** Warning (enabled by default) · **Auto-fixable:** Yes

    **Docker docs:** [from-as-casing](https://docs.docker.com/reference/build-checks/from-as-casing/)

    ```dockerfile theme={null}
    # Violation: FROM is uppercase but AS is lowercase (or vice versa)
    FROM alpine as builder
    # or
    from alpine AS builder
    ```
  </Accordion>

  <Accordion title="buildkit/InvalidDefinitionDescription 🔧 — Warning (off by default)">
    Comments for build stages or arguments should follow the format: `# <arg/stage name> <description>`. If this is not intended to be a description comment, add an empty line or comment between the instruction and the comment.

    **Severity:** Warning · **Default:** Off (experimental) · **Auto-fixable:** Yes

    **Docker docs:** [invalid-definition-description](https://docs.docker.com/reference/build-checks/invalid-definition-description/)

    ```dockerfile theme={null}
    # Violation: comment does not match the stage name immediately below
    # This is the production builder
    FROM alpine AS builder
    ```
  </Accordion>

  <Accordion title="buildkit/MaintainerDeprecated 🔧 — Warning">
    The MAINTAINER instruction is deprecated; use a label instead to define an image author.

    **Severity:** Warning (enabled by default) · **Auto-fixable:** Yes

    **Docker docs:** [maintainer-deprecated](https://docs.docker.com/reference/build-checks/maintainer-deprecated/)

    ```dockerfile theme={null}
    FROM alpine
    # Violation: MAINTAINER is deprecated
    MAINTAINER Jane Doe <jane@example.com>
    ```
  </Accordion>

  <Accordion title="buildkit/NoEmptyContinuation 🔧 — Warning">
    Empty continuation lines will become errors in a future release.

    **Severity:** Warning (enabled by default) · **Auto-fixable:** Yes

    **Docker docs:** [no-empty-continuation](https://docs.docker.com/reference/build-checks/no-empty-continuation/)

    ```dockerfile theme={null}
    FROM alpine
    # Violation: trailing backslash on an otherwise empty continuation line
    RUN echo "hello" \
        \
        && echo "world"
    ```
  </Accordion>

  <Accordion title="buildkit/StageNameCasing 🔧 — Warning">
    Stage names should be lowercase.

    **Severity:** Warning (enabled by default) · **Auto-fixable:** Yes

    **Docker docs:** [stage-name-casing](https://docs.docker.com/reference/build-checks/stage-name-casing/)

    ```dockerfile theme={null}
    # Violation: stage name uses mixed or uppercase letters
    FROM alpine AS Builder
    FROM ubuntu AS PROD
    ```
  </Accordion>
</AccordionGroup>
