Dockerfile Linter

Dockerfile Linter

Hadolint-style rules: tag pinning, layer caching, apt-get patterns, root user, missing HEALTHCHECK, COPY vs ADD, multi-stage opportunities.

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

What This Tool Does

Dockerfile Linter is built for deterministic developer and agent workflows.

Lint Dockerfiles against hadolint-style rules: latest-tag pins, layer-cache misses, apt-get install patterns, root user, missing HEALTHCHECK, COPY vs ADD, multi-stage opportunities. Gives severity badges and fix snippets.

Use How to Use for execution steps and FAQ for constraints, policies, and edge cases.

Last updated:

This tool is provided as-is for convenience. Output should be verified before use in any production or critical context.

Agent Invocation

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.

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.

Frequently Asked Questions

Is this a port of hadolint?
It implements a hadolint-compatible subset of rules (DL3007 latest tag, DL3009 apt cleanup, DL3015 no-install-recommends, DL3002 root user, DL3025 exec form, DL4006 pipefail, DL3057 healthcheck) plus a few extras.
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.