Dockerfile linter and fixer
BetaPaste a Dockerfile to get a scored review of security, reliability and image-size issues. Many findings come with a one-click fix that edits the Dockerfile for you.
Runs entirely in your browser — your input is never uploaded.
Everything is checked in your browser; nothing is uploaded.
What the linter does
Paste a Dockerfile, including multi-stage builds, line continuations and RUN <<EOF heredocs. The tool parses every instruction, checks it against the practices that keep images small, reproducible and safe, and gives the file a score. Each finding shows the line, why it matters and how to fix it.
When the fix needs no decision from you, Apply fix edits the Dockerfile in place. Every line it changes stays highlighted, the card stays in the list marked as fixed, and Undo on that card reverts just that fix. Fixes that need real knowledge of your app, such as which version to pin or which URL to health-check, stay manual.
What it checks
| Area | Checks | Auto-fix |
|---|---|---|
| Security | runs as root (no USER, or USER root last), secrets in ENV or ARG, sudo in RUN, curl … | sh | adds USER 10001, removes sudo |
| Reliability | unpinned FROM (:latest or no tag), apt-get install without -y, apt-get update in its own RUN, npm install instead of npm ci, shell-form CMD/ENTRYPOINT, several CMDs in one stage, relative WORKDIR, apt-get upgrade, no HEALTHCHECK | -y, npm ci, exec-form CMD, removes ignored CMDs |
| Image size and cache | missing --no-install-recommends, apt lists left in the layer, apk add without --no-cache, pip install without --no-cache-dir, COPY . . before installing dependencies | adds the flags and the cleanup |
| Hygiene | ADD for plain local files, deprecated MAINTAINER, cd inside RUN | ADD → COPY, MAINTAINER → LABEL |
The rules follow Docker’s Dockerfile best practices and overlap with the most common hadolint checks.
Example: fixing the sample
The sample scores 41/100 (D) with 16 findings, 10 of which can be fixed automatically. Applying every fix produces:
FROM node:latest
LABEL org.opencontainers.image.authors="Jane Doe <[email protected]>"
ARG NPM_TOKEN
ENV NODE_ENV=production
RUN apt-get update
RUN apt-get update && apt-get install --no-install-recommends -y curl git \
&& rm -rf /var/lib/apt/lists/*
RUN curl -fsSL https://example.com/install.sh | bash
WORKDIR app
COPY package.json package-lock.json ./
RUN npm ci --omit=dev
COPY . .
RUN chown -R node:node /app
EXPOSE 3000
USER 10001
CMD ["npm", "start"]
That scores 78/100 (B). The six findings left need a decision: pin node to a version, delete the standalone apt-get update, verify the install script instead of piping it to bash, make WORKDIR absolute, pass NPM_TOKEN as a build secret and add a HEALTHCHECK.
Pitfalls the rules are based on
- Shell-form
CMDignoresdocker stop.CMD npm startruns under/bin/sh -c, which does not forwardSIGTERM. Stops wait the full timeout (10 s in Docker, 30 s by default in Kubernetes) and end inSIGKILL. apt-get updateon its own line goes stale. Docker caches that layer, so weeks laterapt-get installruns against an old index and fails with 404s. Keepupdateandinstallin the sameRUN.- Deleting files in a later
RUNdoes not shrink the image. The files still exist in the earlier layer. Clean up apt lists and caches in the sameRUNthat created them. ARGis not a secret store. Build arguments are recorded indocker history. UseRUN --mount=type=secretso the value never lands in a layer.- A non-root
USERneeds file permissions. After addingUSER 10001, make sure the app can write where it needs to, for example withCOPY --chown=10001:10001.
Frequently asked questions
- Is my Dockerfile uploaded anywhere?
- No. The Dockerfile is parsed and checked by JavaScript in your browser. Small Dockerfiles are mirrored into the page URL so you can share a review, except when they contain an ENV or ARG that looks like a secret.
- How is this different from hadolint?
- The rules cover the same ground as the most common hadolint checks (pinned base images, apt-get flags, ADD vs COPY, exec-form CMD, USER), but it runs without installing anything and many findings have an Apply fix button. It does not lint the shell scripts inside RUN with ShellCheck; use hadolint in CI for that.
- Which fixes are applied automatically?
- Only fixes that need no decision from you: adding -y and --no-install-recommends to apt-get install, cleaning /var/lib/apt/lists, --no-cache for apk and pip, npm ci instead of npm install, ADD to COPY for local files, exec-form CMD for simple commands, removing sudo and ignored CMDs, and adding USER 10001. Pinning a version or writing a health check stays manual.
- Why does it flag a shell-form CMD?
- CMD npm start runs as /bin/sh -c "npm start". The shell becomes PID 1 and does not forward SIGTERM, so docker stop and Kubernetes wait for the full grace period and then kill the container. CMD ["npm", "start"] runs the process directly.
- Will adding USER 10001 break my image?
- It can if the application writes to directories owned by root. Give that user ownership in the Dockerfile (COPY --chown=10001:10001 or RUN chown), or use the non-root user the base image already provides, such as node in the official Node.js images.
Related tools
docker run to Docker Compose converter
Convert docker run commands into a clean compose.yaml: ports, volumes, env, networks, healthchecks and limits. Runs in your browser.
DockerKubernetes YAML validator and visualizer
Paste Kubernetes manifests to get a resource diagram and a security and best-practice review: privileged pods, root, probes, limits, deprecated APIs.
KubernetesBetaKubernetes manifest generator
Generate a Kubernetes Deployment and Service with resources, probes and a hardened securityContext, plus optional Ingress and HPA.
Kubernetes
Last updated · More Docker tools