Dockerfile Security Checker

Check a Dockerfile for the mistakes that matter.

Runs entirely in your browser — nothing you paste is sent to our servers.

This reads the recipe, not the image. It cannot see what is inside your base image, so a vulnerable library there will not appear. Pair it with an image scanner in CI for the other half.

What this tool does

The findings that matter

Running as root, secrets baked into layers, unpinned base images, exposed datastore ports — each with the line and the fix.

Multi-line aware

Backslash continuations are joined, so a long RUN chain is analysed as one command rather than as fragments.

Multi-stage builds

Stages are counted and the final USER decides the root verdict, so an install step running as root is not a false positive.

In your browser

Dockerfiles carry internal image names and build details. Nothing is uploaded.

Frequently asked questions

What does this check?

The Dockerfile itself: whether the container runs as root, whether secrets are baked into layers, whether the base image is pinned, what ports are exposed, ADD versus COPY, build hygiene, and whether the process is declared in a form that receives signals. Each finding names the line and what to change.

Does it scan the image for vulnerabilities?

No, and that is a real limit. Scanning a built image means pulling it and inspecting the installed packages — a different operation needing a registry and a package database. This reads the recipe, not the result, so it cannot see a vulnerable library inside your base image.

Why does running as root matter inside a container?

Because the container boundary is not a security boundary in the way a VM is. Root inside the container is root in the kernel namespace, so a container escape — through a runtime bug or a permissive mount — starts from a much stronger position. Running as an unprivileged user is one line and removes that head start.

I delete the secret in a later layer. Is it still in the image?

Yes. Every layer is stored and distributed, so anything added in one layer remains readable with "docker history" even after a later layer removes it. Use BuildKit secret mounts, which are never written to a layer, or pass the value at runtime.

Why pin the base image?

Because :latest means two builds of the same Dockerfile can produce different images. A base image update then lands in production without review, and a build you need to reproduce cannot be. Pin a version tag at minimum, and a digest where reproducibility matters.

What is wrong with the shell form of CMD?

In shell form the command runs under /bin/sh -c, which does not forward signals. Your process never receives SIGTERM on shutdown, so it is killed after the grace period instead of closing connections cleanly. The exec form — CMD ["node", "server.js"] — makes your process PID 1 and delivers signals to it.

Is my Dockerfile uploaded?

No. The analysis runs in this tab and makes no request. Dockerfiles routinely contain internal image names and build details, and there is no reason for a checker to see them.

Monitor it, don't just check it

One-off checks catch what is broken today. CertNotify watches your certificates, domains, DNS and code continuously and tells you before something breaks.

Related free tools