Dockerfile Linter

Check Dockerfiles for common security and portability issues.

Open tool

Overview

Paste a Dockerfile and the linter flags the usual security and portability mistakes - latest image tags, missing USER directive, apt-get install without --no-install-recommends and cleanup, unpinned package versions, and combinations that bust layer caching. Findings come with a brief note explaining why the rule exists.

It's for developers and platform engineers who want a quick sanity check before opening a PR. Reach for it when reviewing infrastructure changes, evaluating a base image candidate, or auditing third-party Dockerfiles you're considering vendoring into your own build.

How it works

The linter parses the Dockerfile against the syntax documented in the official Dockerfile reference, then runs a series of rule checks against each instruction. Rules cover the OWASP container security recommendations (run as non-root, minimal base images, no embedded secrets), the Docker BuildKit best-practices guide (multi-stage builds, cache-friendly ordering), and ecosystem-specific gotchas (apt cleanup, npm cache, Python wheel cleanup).

Each rule has a short identifier and severity (info, warning, error) so you can decide which to enforce in CI. The rule set focuses on portable correctness rather than stylistic preferences.

Examples

  • Using latest tag:
    FROM node:latest   # warning: tag this to a specific version
    
  • Running as root:
    FROM ubuntu:22.04
    CMD ["myapp"]      # warning: no USER directive; container runs as root
    
  • Inefficient apt-get:
    RUN apt-get update && apt-get install -y curl
    # warning: missing --no-install-recommends and rm -rf /var/lib/apt/lists/*
    
  • Hardcoded secret:
    ENV AWS_SECRET_KEY=abc123   # error: secret in env layer; use BuildKit secrets
    

FAQ

How does it compare to hadolint?

The rule coverage overlaps with the most-used hadolint rules but is intentionally smaller and focused on actionable findings. For exhaustive linting on a CI matrix, hadolint remains the gold standard.

Does it understand multi-stage builds?

Yes - FROM ... AS stage and stage-named COPY --from=stage are parsed correctly. Findings reference the originating stage.

Will it catch shell injection?

It flags obvious patterns (unquoted $VAR in RUN) but isn't a full shell parser. Treat the output as a screening pass, not a security audit.

Why does it warn about ADD?

ADD has surprise behaviours (remote URL fetching, automatic tar extraction). COPY is recommended for local files unless you specifically need ADD's features.

Try Dockerfile Linter

An unhandled error has occurred. Reload ×