Dockerfile Linter
Check a Dockerfile for unpinned images, root users, shell-form CMD, apt-get without cleanup, secrets in ENV, ADD misuse and more, with hadolint rule codes.
Free · No sign-up · Your inputs stay in your browser
Input
Lint a Dockerfile
Output
4 errors, 10 other
| Line | Rule | Finding |
|---|---|---|
| 1 | DL3007 warning | :latest changes under you. Pin a version, or a digest for reproducible builds. |
| 2 | DL4000 error | MAINTAINER is deprecated. Use LABEL org.opencontainers.image.authors="...". |
| 3 | SEC001 error | A secret in ENV is baked into the image and visible to anyone who can pull it (docker history). Use RUN --mount=type=secret or runtime environment variables. |
| 5 | DL3059 info | Consecutive RUN instructions. Combining related ones saves layers, especially when a later one deletes what an earlier one downloaded. |
| 5 | DL3014 warning | apt-get install needs -y, or the build stops at the prompt. |
| 5 | DL3015 info | Add --no-install-recommends to skip packages you did not ask for. |
| 5 | DL3009 info | Delete /var/lib/apt/lists/* in the same RUN, or the package index stays in the layer. |
| 6 | DL3059 info | Consecutive RUN instructions. Combining related ones saves layers, especially when a later one deletes what an earlier one downloaded. |
| 6 | DL3003 warning | Use WORKDIR to change directory; a cd only lasts for this RUN. |
| 6 | NPM001 info | npm ci installs exactly what package-lock.json says and fails if it is out of date; prefer it in images. |
| 7 | DL3020 error | Use COPY for files and folders. ADD also fetches URLs and unpacks archives, which is surprising when you did not mean it. |
| 8 | DL3000 error | Use an absolute WORKDIR. |
| 10 | DL3025 warning | Use the JSON (exec) form for CMD, ["executable", "arg"]. The shell form runs under /bin/sh -c, which does not forward SIGTERM, so docker stop waits 10 seconds and kills it. |
| 10 | DL3002 warning | The final stage runs as root. Add a USER with a non-root user before CMD. |
Rule codes match hadolint where one exists (DL...), so a finding can be looked up or silenced the same way; SEC and NPM rules are ours. Run hadolint in CI as well: it also lints the shell inside RUN with ShellCheck, which this does not.
Runs in this browser. Nothing you paste is sent to a server.
About this tool
Method, assumptions, practical next steps, and limits.
The findings that matter most
An unpinned or :latest base image makes builds unreproducible. A final stage running as root turns a container escape into root on the host. A secret in ENV or ARG is stored in the image history for anyone who can pull it. A shell-form CMD runs under /bin/sh, which does not forward SIGTERM, so docker stop waits ten seconds and kills the process without a clean shutdown.
Run hadolint in CI
Rule codes match hadolint where one exists, so findings can be looked up and silenced the same way. hadolint also runs ShellCheck on every RUN instruction, which this browser check does not. The Docker documentation's building best practices explains the reasoning behind most rules.