Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

Dockerfile Linter and Best-Practice Checker

Line-by-line Dockerfile checks, a fixed version as a diff, and a .dockerignore.

Free preview, no sign-upIncluded in your pass Pro tool Pro pass: ₹179 for 30 days No upload Works offline Developer

Try before you buy.

  • Free preview: every count with the first problems of the report (up to 10), and the first lines of the fixed Dockerfile, its diff and the .dockerignore (up to 20).
  • Locked until you unlock it: download and copy.
  • Unlock: Pro pass, ₹179 for 30 days, a one-time payment that never renews.

Ways to unlock shows how to get the full result.

See passes (opens in a new tab)

Printing this result is locked in the free preview.

Checked as you type, in your browser. Ctrl/⌘ + Enter checks now.

Your .dockerignore (optional)

With it, files your COPY lines take but the .dockerignore excludes are found, and the whole-context warning knows what you leave out.

Next steps Done. What next?

All developer tools

About the Dockerfile Linter and Best-Practice Checker

Paste a Dockerfile and get line-by-line findings, each with the reason and a link to Docker’s documentation:

  • Base images without a pinned tag or digest, :latest, and build arguments in FROM that are not declared or leave an invalid image name.
  • Root: a final image with no USER, or USER root.
  • Packages: apt-get install without -y, without apt-get update in the same RUN, without --no-install-recommends or without removing /var/lib/apt/lists; apt-get update alone in its own layer; apk add without --no-cache; yum and dnf without -y and clean all; pip caches.
  • Risky steps: ADD where COPY is clearer, downloads without --checksum, curl … | sh, pipes without pipefail, sudo, chmod 777.
  • Secrets in ENV and ARG, which stay in the image for anyone who pulls it.
  • Commands: shell-form CMD and ENTRYPOINT (your program misses SIGTERM), exec forms that are not valid JSON, a CMD that a shell-form ENTRYPOINT ignores, repeated CMDs.
  • Docker’s build checks: the deprecated MAINTAINER, legacy ENV key value and LABEL key value, relative WORKDIR, EXPOSE with host ports, stage-name casing and duplicates, constant --platform values, COPY --from names that are a typo of a stage, and files that your .dockerignore excludes.

The page also writes a fixed Dockerfile with the safe changes made, shown as a diff, suggests a multi-stage build where build tools end up in the image you ship, and writes a .dockerignore for what you build. The rules are MySmartCoPilot’s own, written from Docker’s documentation. Nothing is uploaded. Without a pass the result is a free preview: every count with the first problems, and the first lines of the fixed Dockerfile, the diff and the .dockerignore. The whole report and every copy and download unlock with a Pro pass.

How to use it

  1. Paste your Dockerfile, open it, or press Load example. Add your .dockerignore if you have one: then files it excludes are found, and the “whole context” warning knows what you exclude.
  2. Read the findings: errors break the build or the image, warnings are risks, notes are advice. Show selects the line; each finding links the Docker page it follows.
  3. Open Fixed Dockerfile to see the safe changes as a diff — merged apt-get update, -y and clean-ups, COPY for local files, exec-form CMD, LABEL for MAINTAINER. Changes that need your decision, such as a USER or a pinned version, stay in the findings.
  4. With a pass, or once the result is unlocked, copy or download the fixed Dockerfile, the suggested .dockerignore and the report; the free preview shows their first lines and locks the copies and downloads.

Examples

apt-get in two layers
Input
RUN apt-get update
RUN apt-get install python3 make g++
Result
RUN apt-get update && apt-get install -y --no-install-recommends python3 make g++ \
    && rm -rf /var/lib/apt/lists/*

A cached apt-get update layer makes later installs use old package lists; without -y the build stops at the confirmation question.

A shell-form CMD
Input
CMD npm start
Result
CMD ["npm", "start"]

In shell form npm runs under /bin/sh, which does not pass SIGTERM on, so docker stop has to kill it.

A secret build argument
Input
ARG NPM_TOKEN
RUN npm ci
Result
Warning (SecretsUsedInArgOrEnv): use a build secret instead: RUN --mount=type=secret,id=npm_token,env=NPM_TOKEN … and docker build --secret id=npm_token,env=NPM_TOKEN.

Where the rules come from

Rules that do the same job as one of Docker’s build checks keep its name — JSONArgsRecommended, SecretsUsedInArgOrEnv, UndefinedArgInFrom, CopyIgnoredFile and the others — so you can match them with the output of docker build --check .. The others follow Docker’s building best practices (apt-get, pipes, ADD or COPY, USER, WORKDIR, pinning base images) and the Dockerfile reference (exec and shell form, HEALTHCHECK, here-documents). Secret names are recognised the way BuildKit recognises them: words such as password, secret, token, key or auth as a whole word of the name (DB_PASSWORD, GITHUB_TOKEN, API_KEY_ID), unless another word of it is public, file or version (PUBLIC_KEY, SECRET_FILE).

Multi-stage builds

When one stage installs compilers or runs npm run build, go build, mvn package or similar, everything it needed stays in the image you deploy. A multi-stage build builds in a first stage and copies only the result into a small runtime image: FROM node:24 AS build … RUN npm run build, then FROM node:24-slim with COPY --from=build /app/dist ./dist. The linter points this out; the restructuring is yours.

Limitations

  • The linter reads the Dockerfile only: it does not pull base images, so it cannot see the USER, ENV or HEALTHCHECK a base image sets, nor check that packages and files exist.
  • Commands inside RUN are read as text (including here-documents), not run in a shell, so unusual scripts may be read too strictly or not strictly enough.
  • The fixed Dockerfile only makes mechanical changes; build it and test it before you replace yours.

Privacy

Everything happens in your browser. What you enter or open here is not uploaded or stored by MySmartCoPilot.

Frequently asked questions

What do I get without a pass?

Without a pass, Dockerfile Linter and Best-Practice Checker shows every count with the first problems of the report (up to 10), and the first lines of the fixed Dockerfile, its diff and the .dockerignore (up to 20). Until you unlock it, the result can’t be downloaded or copied. A Pro, Premium or Ultimate pass, a one-time payment that never renews, unlocks the full result. The pricing page lists the passes and their prices.

Is this like hadolint?

It covers similar ground, and adds Docker’s own build-check names, a fixed Dockerfile with a diff and a .dockerignore. The rules are written from Docker’s documentation; no code from hadolint is used. It runs in your browser.

Why should the image not run as root?

A process that breaks out of the application then has root inside the container, and with a mounted socket or a kernel bug possibly on the host. Create a user (RUN useradd --system --uid 10001 app), give it the files it writes (COPY --chown=app), and switch with USER app before CMD.

Should I pin the base image to a digest?

A tag such as node:24-slim can move to a newer image; a digest (@sha256:…) never changes. Docker’s best practices suggest a digest when builds must be reproducible, with a tool such as Dependabot to update it, and a version tag at the least — never latest.

Is my Dockerfile uploaded?

No. It is read and checked in your browser only.

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.