OFOpsForge

Dockerfile Linter

Local analysis

Static 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.

Quality score0/100
ErrorL1 · no-latest-tag

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

ErrorL1 · run-as-non-root

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

ErrorL6 · no-secret-in-image

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).

ErrorL7 · no-pipe-to-shell

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.

WarningL1 · use-multi-stage

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

WarningL4 · prefer-npm-ci

npm install can mutate the lockfile, hurting reproducibility.

✦ Use npm ci for CI and image builds.

WarningL5 · apt-no-recommends

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/*

WarningL5 · apt-clean-cache

The apt cache is left behind in the image layer.

✦ Run rm -rf /var/lib/apt/lists/* within the same RUN instruction.

InfoL9 · add-healthcheck

No HEALTHCHECK — orchestrators cannot tell whether the container is healthy.

✦ HEALTHCHECK CMD wget -qO- http://127.0.0.1:PORT/healthz || exit 1