Dockerfile Validator & Linter

Catch structural errors and common antipatterns: ADD with URL, sudo in RUN, :latest tags, apt-get bloat, missing USER. Validates every Dockerfile instruction — runs entirely in your browser.

What is a Dockerfile validator?

A Dockerfile validator reads your Dockerfile and reports problems before docker build runs them. It checks structure (every line is a known instruction; FROM comes first), warns on antipatterns that produce bloated or insecure images, and surfaces the small mistakes — a missing --no-install-recommends, a stray sudo, an un-pinned :latest tag — that turn into production headaches.

It is a fast feedback loop you can run from any browser. Pair it with hadolint in CI for full coverage; reach for this validator when you want a sanity check during code review or while iterating on a Dockerfile in your editor.

How to validate a Dockerfile — 4 steps

  1. Paste the Dockerfile. Single- or multi-stage, any base image. Click Load Sample to see how the linter flags antipatterns.
  2. Click Validate. The parser joins backslash continuations, splits instructions, and runs structural + antipattern checks.
  3. Read the issues. Errors are structural (must fix before docker build); warnings are antipatterns; info notes are gentle suggestions.
  4. Fix and re-run. Pin tags, drop sudo, add cleanup steps, set a USER — re-validate until the result is clean.

Sample Dockerfile and result

Input

FROM node
ADD https://example.com/file.tar /tmp/
RUN sudo apt-get install python
COPY . /app
CMD ["node", "server.js"]

Result

Found 0 errors, 4 warnings, 2 info notes (5 instructions).

[WARN]  line 1: FROM "node" has no tag — defaults to :latest. Pin a specific version.
[WARN]  line 2: ADD with a URL is discouraged — use RUN curl/wget…
[WARN]  line 3: RUN uses "sudo" — containers run as root by default…
[WARN]  line 3: apt-get install without --no-install-recommends…
[INFO]  line 4: COPY . copies the entire build context — make sure .dockerignore is present.
[INFO]  line 5: No USER instruction — the container will run as root.

Security Antipatterns

sudo in RUN, missing USER (root by default), unpinned :latest tags — the security smells reviewers care about.

Image-Size Antipatterns

apt-get without cleanup, ADD downloads instead of RUN curl, COPY of unintended files — the bloat that slows pulls and CI.

Browser-Local

Build args, internal registries, and proprietary base images stay on your device. Verify in DevTools — zero requests on Validate.

Use cases

  • check_circleIaC review: catch security and bloat antipatterns before merging a Dockerfile change
  • check_circleCI lint step: copy/paste from CI logs to debug a hadolint failure interactively
  • check_circleGitOps: review base-image bumps for un-pinned tags before they hit production
  • check_circleSecurity review: surface sudo, missing USER, and ADD-with-URL antipatterns
  • check_circleOnboarding: teach engineers Dockerfile best practices with concrete line-by-line feedback
  • check_circleImage-size reduction: catch apt-get cleanup gaps that add 50–200 MB per layer

HCL vs JSON vs YAML for IaC

AspectDockerfileYAML (Compose)HCL / JSON
Used bydocker builddocker composeTerraform / Packer
StyleImperativeDeclarativeDeclarative
Build cacheLayer-awareImage-levelN/A
ValidationThis toolYAML validatorterraform validate
Best forImage buildService stacksCloud resources

More IaC validators

Lint Kubernetes manifests, convert Terraform HCL, and validate raw YAML — all browser-side.

Frequently Asked Questions

What does the Dockerfile validator check?

Three layers. First, structure: every non-blank, non-comment line must start with a recognised Dockerfile instruction (FROM, RUN, CMD, ENTRYPOINT, COPY, ADD, WORKDIR, ENV, ARG, EXPOSE, USER, VOLUME, LABEL, ONBUILD, STOPSIGNAL, HEALTHCHECK, SHELL). Second, ordering: FROM must come first, with only ARG permitted before it. Third, antipatterns: ADD with a URL, sudo in RUN, :latest tags, apt-get install without cleanup, missing USER, deprecated MAINTAINER.

Why warn about FROM with :latest?

Because images move. A build that succeeds today on node:latest may fail tomorrow when node:latest points to a new major version. Pin a specific tag (node:20-alpine) or, for production, a digest (node@sha256:…). The validator surfaces the issue so reproducibility regressions are caught at review time, not at 3 a.m. when the build pipeline breaks.

Why is ADD with a URL discouraged?

Two reasons. First, ADD downloads the file but cannot verify a checksum, so a tampered upstream silently corrupts your image. Second, the downloaded file becomes a layer in the image — even after deletion in a later RUN, the bytes are stored forever. Use RUN curl -fsSL <url> -o /tmp/x && sha256sum -c <(echo "<digest> /tmp/x") in a single layer instead.

Why is sudo inside RUN flagged?

Containers run as root by default — sudo is unnecessary and adds an attack surface (the sudoers file, the sudo binary). Drop sudo, install software directly, and switch to a non-root user with USER appuser before CMD. This produces smaller images and follows the principle of least privilege.

Does this replace hadolint?

No. hadolint is a comprehensive linter with hundreds of rules; this validator focuses on the highest-value antipatterns and runs in your browser without installing anything. Use this tool for quick reviews and PR feedback; install hadolint in CI for full coverage.

Is my Dockerfile uploaded?

No. Parsing and linting run in JavaScript inside your browser. Dockerfiles often reference internal registries, secret build args, or proprietary build steps — none of it leaves the device. Verify in DevTools → Network: clicking Validate produces zero requests.

How does the validator handle multi-stage builds?

Each FROM starts a new build stage. The validator resets per-stage tracking (so the missing-USER info note is evaluated at the end of the final stage). All other rules — ADD with URL, sudo in RUN, :latest tags — fire wherever they appear.

What about COPY . /app — should I avoid it?

Not necessarily, but ensure a .dockerignore is present to exclude .git, node_modules, build artefacts, and secrets. The validator emits an info note when COPY . is used as a reminder. A good .dockerignore keeps build context small, build cache hot, and secrets out of images.

Dockerfile Validator — Lint Dockerfiles Online