Skip to content
OpsAtlas

Dockerfile linter and fixer

Beta

Docker

Paste 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.

Paste a Dockerfile or load the sample to see a scored best-practice review.

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

AreaChecksAuto-fix
Securityruns as root (no USER, or USER root last), secrets in ENV or ARG, sudo in RUN, curl … | shadds USER 10001, removes sudo
Reliabilityunpinned 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 cachemissing --no-install-recommends, apt lists left in the layer, apk add without --no-cache, pip install without --no-cache-dir, COPY . . before installing dependenciesadds the flags and the cleanup
HygieneADD for plain local files, deprecated MAINTAINER, cd inside RUNADD → 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 CMD ignores docker stop. CMD npm start runs under /bin/sh -c, which does not forward SIGTERM. Stops wait the full timeout (10 s in Docker, 30 s by default in Kubernetes) and end in SIGKILL.
  • apt-get update on its own line goes stale. Docker caches that layer, so weeks later apt-get install runs against an old index and fails with 404s. Keep update and install in the same RUN.
  • Deleting files in a later RUN does not shrink the image. The files still exist in the earlier layer. Clean up apt lists and caches in the same RUN that created them.
  • ARG is not a secret store. Build arguments are recorded in docker history. Use RUN --mount=type=secret so the value never lands in a layer.
  • A non-root USER needs file permissions. After adding USER 10001, make sure the app can write where it needs to, for example with COPY --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.
  • 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.

    Docker
  • Kubernetes 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.

    KubernetesBeta
  • Kubernetes 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