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.