Dockerfile Linter
Lint Dockerfiles against ~25 hadolint-style rules. Catches the highest-value mistakes — floating tags, missing USER, apt cache leaks, shell-form CMDs.
Errors
1
Warnings
12
Info
3
- warningDL3007line 1
Avoid :latest tag — pin a specific version
Hint: Use a digest or specific tag for reproducible builds
- warningDL4000line 2
MAINTAINER is deprecated — use LABEL maintainer="..."
- warningDL3000line 4
Use absolute WORKDIR path
- warningDL3020line 5
Use COPY instead of ADD for files and folders
Hint: ADD has implicit features (URL fetch, archive extract) that surprise readers
- warningDL3015line 7
apt-get install: add --no-install-recommends to keep image small
- warningDL3009line 7
Clean up apt-get caches in the same RUN: rm -rf /var/lib/apt/lists/*
- infoDL3008line 7
Pin versions in apt-get install (pkg=version)
- warningDL3014line 7
Add -y to apt-get install to avoid interactive prompts
- warningDL3015line 9
apt-get install: add --no-install-recommends to keep image small
- warningDL3009line 9
Clean up apt-get caches in the same RUN: rm -rf /var/lib/apt/lists/*
- infoDL3008line 9
Pin versions in apt-get install (pkg=version)
- errorDL3004line 9
Do not use sudo — it leads to unpredictable behavior
- warningDL3011line 11
EXPOSE port "99999" is out of range (1..65535)
- warningDL3025line 13
CMD should use the JSON exec form ["cmd", "arg"] not shell form
- warningDL3002line 1
No USER set — image runs as root
Hint: Add a USER instruction with a non-root user before CMD/ENTRYPOINT
- infoDL3009line 9
Multiple RUN apt-get lines — combine into one to reduce layers (2 found)
About Dockerfile Linter
Lint Dockerfiles against ~25 hadolint-style rules covering the highest-value problems: floating tags, missing USER, ADD vs COPY, apt-get cache leaks, pip/npm version pinning, shell-form CMD/ENTRYPOINT, sudo usage, non-absolute WORKDIR, deprecated MAINTAINER, and out-of-range EXPOSE ports. All analysis runs in your browser.
Rule categories
Security
Missing USER (runs as root), sudo usage, :latest tags, ADD with URLs.
Image size
apt-get cache not cleaned, --no-install-recommends missing, pip --no-cache-dir missing, multiple apt-get RUN layers.
Correctness
Shell-form CMD/ENTRYPOINT, non-absolute WORKDIR, cd in RUN, out-of-range EXPOSE.
Maintenance
Deprecated MAINTAINER, unpinned apt/pip/npm versions.
Pipeline
- Docker Compose Visualizer — visualize the service stack that uses this Dockerfile.
- Kubernetes Validator — validate the K8s manifests that deploy this image.
Frequently asked
- Why should I avoid the :latest tag?
- The :latest tag is mutable — it points to a different image every time the upstream maintainer pushes a new build. Using :latest means your image can change between builds without any change to your Dockerfile, breaking reproducibility. Pin to a specific version tag (e.g. nginx:1.27.0) or a digest (e.g. nginx@sha256:...) for reproducible builds.
- Why should I add a USER instruction?
- By default, Docker containers run as root. If an attacker exploits a vulnerability in your application, they have root access inside the container. Adding a non-root USER reduces the blast radius. Create a dedicated user in your Dockerfile: RUN addgroup -S app && adduser -S app -G app, then USER app.
- Why use COPY instead of ADD?
- ADD has two implicit behaviours that surprise readers: it can fetch URLs (downloading arbitrary content at build time) and it automatically extracts tar archives. COPY does exactly one thing: copy files from the build context. Use COPY for files and directories; use ADD only when you specifically need the archive extraction feature.
- Why should I clean apt-get caches in the same RUN?
- Docker layers are immutable. If you run apt-get install in one RUN and rm -rf /var/lib/apt/lists/* in a separate RUN, the cache files are still present in the first layer and contribute to the final image size. Combining them in a single RUN ensures the cache is never committed to any layer.
- What is the exec form vs shell form for CMD and ENTRYPOINT?
- Shell form (CMD echo hello) runs the command via /bin/sh -c, which means signals like SIGTERM are sent to the shell, not your process. This causes graceful shutdown to fail. Exec form (CMD ["echo", "hello"]) runs the command directly as PID 1, so signals are delivered correctly. Always use exec form for CMD and ENTRYPOINT.
Related Tools
CI/CD Workflow Builder
Visually build GitHub Actions workflows with live YAML preview, syntax validation, and starter templates.
Kubernetes Manifest Validator
Validate Kubernetes manifests and detect common misconfigurations.
Nginx Config Generator
Generate production-ready Nginx configs for SPA, reverse proxy, PHP-FPM, and Node.js with SSL and security headers.
HTTP Status Code Reference
Searchable reference of all HTTP status codes with descriptions.
cURL to Code Converter
Convert cURL commands to fetch, Python, PHP, Java, and Apex code.
JSON Schema Generator
Auto-generate JSON Schema from sample JSON data.