DevKit
Tester

Dockerfile Linter

Check a Dockerfile for best-practice issues like unpinned tags and root user.

Last updated: August 2026

Checks common Dockerfile best practices (pinned tags, non-root user, layer hygiene). Not a substitute for hadolint in CI.

Share:

Was this tool helpful?

Catching Dockerfile mistakes early

A Dockerfile linter scans your build instructions for patterns that lead to bloated images, broken caching, or security weaknesses. It encodes the lessons teams usually learn the hard way, like why a floating tag causes irreproducible builds, so you fix them before the image ships rather than after an incident.

The issues worth fixing

Unpinned base image tags such as node:latest make builds non-reproducible, since latest drifts over time. Running as root is the default and a real risk; a compromised process then has root in the container. Combining apt-get update and install in separate layers lets a stale cached update serve old package lists. Copying the whole context before installing dependencies busts the layer cache on every source change.

Example

# flagged
FROM node:latest
COPY . .
RUN npm install

# improved
FROM node:20.11-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci && npm cache clean --force
COPY . .
USER node

Pinning the tag, copying the manifest before the source so dependency layers cache, using npm ci for reproducible installs, and dropping to a non-root USER address the common findings at once.

Caching and image size

Docker caches each layer, so instruction order is not cosmetic: put the things that change rarely (dependency installs) before the things that change constantly (your source). A multi-stage build keeps compilers and dev dependencies out of the final image, often cutting its size dramatically. The linter nudges toward both.

FAQ

Why avoid latest if it always pulls the newest? Because newest is a moving target. A build that passed today can fail or behave differently tomorrow when latest points somewhere new. Pinning makes builds repeatable.

Is running as root really a problem inside a container? Containers are not a hard security boundary. Combined with a kernel or runtime escape, root in the container is a meaningful step toward root on the host, so dropping privileges is cheap insurance.