Skip to content
xt-tools

Dockerfile linter

Check a Dockerfile for common mistakes and best-practice issues, with an explanation for each finding.

Try:
All rules (51)
Rules
RuleSeverityChecks forWhy it matters
XT1001ErrorUnknown instructionThe builder stops with a parse error when it meets an instruction it does not know.
XT1002ErrorFROM must come firstOnly parser directives, comments and global ARG instructions may appear before the first FROM.
XT1003ErrorInvalid escape directiveThe escape directive only accepts a backslash or a backtick.
XT1004ErrorMissing argumentsEvery instruction needs at least one argument, so the build fails here.
XT1005WarningWhitespace after line continuationInvisible spaces after the escape character are easy to miss and some tools stop treating the line as continued.
XT1006ErrorUnterminated heredocWithout its closing delimiter the heredoc swallows the rest of the file.
XT1007WarningEmpty continuation lineBlank lines inside a continued instruction are deprecated and may become an error.
XT1008WarningFile ends with a line continuationThe last instruction expects another line that never comes, which usually means something was cut off.
XT1009InfoInconsistent instruction casingInstructions are case-insensitive, but mixing cases makes the file harder to read; uppercase is the convention.
XT1101WarningBase image without a tagWithout a tag the builder pulls "latest", so the same Dockerfile can produce different images over time.
XT1102WarningBase image uses the latest tagThe "latest" tag moves whenever a new version is pushed, which makes builds unpredictable.
XT1103ErrorDuplicate stage nameStage names must be unique so that FROM and COPY --from can refer to them unambiguously.
XT1104ErrorCOPY --from refers to an unknown stageA stage can only copy from stages defined above it; anything else is pulled as an image, which is rarely intended.
XT1105ErrorMalformed FROMFROM takes an image, optionally followed by AS and a stage name that starts with a letter.
XT1106InfoHard-coded platformA fixed --platform prevents multi-platform builds; $BUILDPLATFORM or $TARGETPLATFORM keep them working.
XT1107InfoAS casing differs from FROMMatching the casing of FROM and AS keeps the file consistent.
XT1108WarningUndefined variable in FROMVariables in FROM only come from ARG instructions placed before the first FROM, or from built-in platform arguments.
XT1109WarningCOPY --from names an imageA --from value that is not a stage is pulled as an image; that works, but a typo in a stage name looks the same.
XT1201WarningMAINTAINER is deprecatedMAINTAINER was replaced by a label such as org.opencontainers.image.authors.
XT1202WarningLegacy "key value" formThe space-separated form only allows one variable and is deprecated; "key=value" is clearer.
XT1301WarningFinal stage runs as rootWithout a USER instruction the container runs as root, which makes a container escape far more damaging.
XT1302WarningLast USER is rootSwitching back to root at the end means the container runs with full privileges.
XT1303Warningsudo in RUNBuild steps already run as the current USER; sudo adds an unneeded binary and confusing privilege changes.
XT1401Warningapt-get install without -yWithout -y apt-get waits for a confirmation that never comes in a build and aborts.
XT1402Warningapt-get install without --no-install-recommendsRecommended packages are rarely needed in an image and can add a lot of size and attack surface.
XT1403Warningapt lists not cleanedThe package lists in /var/lib/apt/lists stay in the layer unless they are removed in the same RUN.
XT1404WarningUpgrading all packagesUpgrading everything in a build makes images unpredictable; use a newer base image or pin the packages you need.
XT1405Warningapt instead of apt-getapt is meant for interactive use and its command-line interface is not stable for scripts.
XT1406Warningapk add without --no-cacheWithout --no-cache the package index stays in the layer and bloats the image.
XT1407Warningyum/dnf cache not cleanedPackage manager caches stay in the layer unless they are cleaned in the same RUN.
XT1408WarningPackage install without a yes flagWithout a non-interactive flag the package manager waits for a confirmation and the build fails.
XT1409Warningpip install without --no-cache-dirpip keeps downloaded packages in its cache, which ends up in the image's layer.
XT1410Infonpm install instead of npm cinpm ci installs exactly what the lockfile says, so builds are reproducible.
XT1411Warningapt-get update on its ownA cached update layer goes stale, so a later install can fail or fetch outdated packages; update and install in the same RUN.
XT1501WarningPiping a download into a shellRunning a script straight from the network executes whatever the server sends, without any verification.
XT1502Warningcd in RUNWORKDIR sets the directory for every following instruction and is easier to follow than cd inside commands.
XT1503InfoConsecutive RUN instructionsEach RUN creates a layer; related commands joined with && produce fewer, smaller layers.
XT1504InfoPipe without pipefailIn a pipeline only the last command decides success, so a failing download can go unnoticed.
XT1601WarningRelative WORKDIRA relative WORKDIR depends on every earlier WORKDIR, which is easy to break; absolute paths are clearer.
XT1701WarningADD for local filesCOPY is more predictable for local files; ADD also extracts archives and downloads URLs.
XT1702WarningADD from a URLADD downloads without verifying the file; add --checksum, or download and verify it in a RUN step.
XT1703ErrorSeveral sources need a directory destinationWhen COPY or ADD has more than one source, the destination must be a directory ending with a slash.
XT1801WarningShell form for CMD or ENTRYPOINTIn shell form the process runs under /bin/sh -c, which does not forward signals, so the container cannot stop gracefully.
XT1802WarningInstruction overridden later in the stageOnly the last CMD, ENTRYPOINT or HEALTHCHECK of a stage takes effect.
XT1803ErrorInvalid exec formWhen the JSON array cannot be parsed the builder silently falls back to shell form and runs the brackets as a command.
XT1901ErrorInvalid EXPOSEEXPOSE takes container ports (1–65535 or a range) with an optional /tcp, /udp or /sctp protocol.
XT2001WarningSecret in ENV or ARGENV and ARG values are stored in the image metadata and history, where anyone with the image can read them.
XT2002InfoSecret passed as a build argumentBuild arguments show up in the image history; a secret mount (RUN --mount=type=secret) keeps them out of it.
XT2101InfoNo HEALTHCHECKWithout a HEALTHCHECK, Docker cannot tell a running container from a working one.
XT2103ErrorMalformed HEALTHCHECKHEALTHCHECK takes either NONE or CMD followed by a command.
XT2204ErrorInvalid ONBUILD triggerONBUILD cannot wrap FROM, MAINTAINER or another ONBUILD.

The rule set and its wording are this tool’s own. The Dockerfile is checked in your browser and never leaves it.