Dockerfile Linter
Local analysisStatic analysis based on core hadolint rules plus security best practices — checks reproducibility, image size, secret exposure, and supply-chain risk. Everything runs in your browser.
Base image 'node' has no explicit tag or uses :latest, which breaks build reproducibility.
✦ Pin a specific version tag or digest, e.g. node:22-alpine
The final stage runs as root, which magnifies the impact of a container escape.
✦ Add an unprivileged user, e.g. RUN adduser -S app && ... USER app
A value that looks like a secret is hardcoded into an image layer — it stays in the image history forever.
✦ Use runtime env vars / a secret manager, or a BuildKit secret mount (--mount=type=secret).
A remote script is piped into a shell without verification — a supply-chain risk.
✦ Verify a checksum before executing, or install from an official package.
Build tools end up in the runtime image, inflating its size and attack surface.
✦ Split into a multi-stage build: FROM ... AS build → COPY only the artifacts into a slim/alpine runtime stage
npm install can mutate the lockfile, hurting reproducibility.
✦ Use npm ci for CI and image builds.
apt-get install without --no-install-recommends pulls in unnecessary packages.
✦ apt-get install -y --no-install-recommends <pkg> && rm -rf /var/lib/apt/lists/*
The apt cache is left behind in the image layer.
✦ Run rm -rf /var/lib/apt/lists/* within the same RUN instruction.
No HEALTHCHECK — orchestrators cannot tell whether the container is healthy.
✦ HEALTHCHECK CMD wget -qO- http://127.0.0.1:PORT/healthz || exit 1