Skip to content

Dockerfile Linter

Lint a Dockerfile with hadolint-style rules for latest tags, apt-get, root user, ADD vs COPY, cache order and HEALTHCHECK, with a score and fixes.

Dockerfile Linter

Score
0
14 findings
Dockerfile
warningDL3007line 1

Pin base image to a specific version or digest. ':latest' (or no tag) makes builds non-reproducible.

Fix snippet
FROM node:24.04   # or @sha256:<digest>
infoMULTISTAGE-OPPORTUNITYline 1

Build artifacts and runtime live in the same image. Multi-stage builds shrink the final image.

Fix snippet
FROM node:24 AS build
...
FROM node:24-slim
COPY --from=build /app/dist ./dist
warningCACHE-ORDERline 5

COPY . . before installing dependencies wastes the cache: any source change reruns install.

Fix snippet
COPY package*.json ./
RUN npm ci
COPY . .
warningDL3009line 7

Delete the apt-get lists after installing to keep the image small.

Fix snippet
RUN apt-get update && apt-get install -y --no-install-recommends pkg && rm -rf /var/lib/apt/lists/*
infoDL3015line 7

Avoid recommended packages: pass --no-install-recommends to apt-get install.

Fix snippet
apt-get install -y --no-install-recommends <pkg>
infoDL3008line 7

Pin package versions in apt-get install (pkg=version).

Fix snippet
apt-get install -y --no-install-recommends pkg=1.2.3
warningDL3009line 8

Delete the apt-get lists after installing to keep the image small.

Fix snippet
RUN apt-get update && apt-get install -y --no-install-recommends pkg && rm -rf /var/lib/apt/lists/*
infoDL3015line 8

Avoid recommended packages: pass --no-install-recommends to apt-get install.

Fix snippet
apt-get install -y --no-install-recommends <pkg>
infoDL3008line 8

Pin package versions in apt-get install (pkg=version).

Fix snippet
apt-get install -y --no-install-recommends pkg=1.2.3
infoDL3020line 10

ADD with a URL skips checksum verification. Prefer RUN curl with explicit checksum.

Fix snippet
RUN curl -fsSL <url> -o /tmp/file && echo "<sha256>  /tmp/file" | sha256sum -c
warningDL3003line 12

Use WORKDIR to switch directories instead of `cd` in a RUN.

Fix snippet
WORKDIR /app
warningDL3002line 14

Container ends up as root. Switch to a non-privileged user before CMD/ENTRYPOINT.

Fix snippet
USER app
warningDL3025line 18

Use JSON array form for CMD so signals (SIGTERM) propagate correctly.

Fix snippet
CMD ["npm", "start"]
infoHEALTHCHECK-MISSINGline 18

No HEALTHCHECK defined. Orchestrators rely on it to detect zombie containers.

Fix snippet
HEALTHCHECK --interval=30s --timeout=3s CMD curl -f http://localhost:3000/health || exit 1

Updated . Provided as is. Check the output before you rely on it in production.

How to use Dockerfile Linter

  1. 1

    Paste your Dockerfile

    Drop the full Dockerfile (multi-stage included) into the editor on the left. The linter parses FROM/RUN/COPY/ADD/USER/EXPOSE/HEALTHCHECK and tracks build stages, line continuations, and string interpolations.

  2. 2

    Review findings by severity

    Findings stream into the right panel grouped by severity — error, warning, info, style. Each finding shows the rule code, line number, and a one-sentence explanation of why the pattern matters in production.

  3. 3

    Filter to focus

    Click any severity card to filter findings down to that level. Useful for fixing all warnings first before chasing style issues, or reviewing only errors during a CI gate triage.

  4. 4

    Copy fix snippets

    Most rules ship a copy-ready fix snippet (pin versions, use --no-install-recommends, switch to JSON CMD form, add HEALTHCHECK). Click Copy on any snippet to paste it directly into the Dockerfile.

  5. 5

    Track the score

    The overall score (0–100) drops on each finding by severity weight. Aim for 80+ before merging — that range usually means non-root user, pinned base image, sensible layer order, and a HEALTHCHECK present.

Questions and answers

Is this a port of hadolint?
No. It implements a subset of hadolint rules (DL3002, DL3003, DL3007, DL3008, DL3009, DL3015, DL3020, DL3025, DL4006) for root user, cd, latest tags, apt pinning and cleanup, ADD vs COPY, exec form and pipefail, plus its own checks for cache order, HEALTHCHECK, EXPOSE and multi-stage builds.
Why does the score drop so fast on a fresh Dockerfile?
Default-mode Dockerfiles often hit four or five common issues at once (latest tag, root user, no HEALTHCHECK, COPY-then-install). Fix the warnings and the score climbs into the 80s without much rewriting.
Can I configure or disable rules?
Not yet. The current ruleset is fixed and tuned for general-purpose images. Severity filtering on the cards lets you focus on the categories that matter for your CI gate (errors and warnings, ignore style).
Does it send my data to a server?
No. Parsing, rule evaluation, and scoring all run in your browser. The Dockerfile contents are never uploaded, which matters for proprietary images that bake in private packages or registry credentials.
Does it follow ARG/ENV substitution?
Partially. Variable substitution is not expanded, so rules match the literal text. This is intentional — most security and cache-locality issues are detectable from the literal directive without full template evaluation.
For AI agents: how to call this tool

Machine-readable contract, endpoints and examples. Humans can ignore this section.

Best Path For Builders

Browser workflow

Runs instantly in the browser with private local processing and copy/export-ready output.

Browser Workflow

This tool is optimized for instant in-browser execution with local data handling. Run it here and copy/export the output directly.

/dockerfile-linter/

For automation planning, fetch the canonical contract at /api/tool/dockerfile-linter.json.