Dockerfile & Docker Compose Security Analyzer
Check a Dockerfile or docker-compose.yml for root users, secrets, latest tags, privileged containers, exposed database ports and the Docker socket. Runs in your browser.
Runs in your browser Your input never leaves your device.
Paste a Dockerfile or a docker-compose.yml / compose.yaml. It is read in your browser: nothing is uploaded, no image is pulled and no registry is contacted, so tags and digests are judged by their form, not looked up.
Findings
Build stages
What is checked
Dockerfile: base images without a tag, on latest or not pinned by digest; running as root; secrets in ENV and ARG, in files copied in, and credentials written in the file; ADD from URLs; downloads piped into a shell; disabled certificate and signature checks; chmod 777; sudo; package manager hygiene (apt-get, pip, wget) and the other hadolint checks (shell form CMD, missing pipefail, repeated CMD, multi-stage mistakes). Compose: privileged containers, host network, PID and IPC namespaces, dangerous capabilities, disabled seccomp and AppArmor, mounts of the Docker socket and sensitive host folders, database and admin ports published on every interface, images on latest, secrets in environment and build arguments, root users, devices, and references to services, networks and volumes that do not exist. Both: unknown keys and structure errors.
Findings describe the text you pasted, not running containers. Run hadolint and a Compose linter in CI, and scan built images with a vulnerability scanner.
Report a problem with this tool
About this tool
Docker images and Compose files fail in predictable ways: the container runs as root, a base image is on latest, a token ends up in an ENV line or a build argument and so in the image history, a download is piped into a shell, and a Compose file publishes a database on every interface or mounts the Docker socket. This tool reads a Dockerfile or a Compose file in your browser and reports them with the line of each. The Dockerfile parser handles line continuations, comments inside continuations, parser directives, JSON and shell forms and heredocs, and splits the file into build stages; the rules that come from hadolint keep its code (DL3006, DL3007, DL3002, DL3064 and so on) and were compared with hadolint on many generated Dockerfiles, and the instruction splitting with the python dockerfile-parse library. For Compose it checks the keys at the top level, in services, healthchecks, deploy and the networks, volumes, secrets and configs sections against the official Compose Specification (compared with the schema on random files; keys deeper in build and ports are not checked) and looks at privileged mode, host namespaces, capabilities, security profiles, mounts of the Docker socket and sensitive host folders, published ports (database and admin ports on 0.0.0.0, which also bypass most host firewalls), image tags, secrets in environment and build arguments, root users, devices and references to services, networks and volumes that do not exist. It never contacts a registry, so it cannot tell whether a tag exists or what an image contains; for that scan the built image.
How to use it
- Paste the Dockerfile or Compose file, or load it. The type is detected, or choose it.
- Read the findings from the top: critical and high ones give an attacker a path to the host or to your secrets.
- Fix them in the file: use a non-root USER, pin versions or digests, pass secrets with BuildKit secrets or runtime secrets, bind published ports to 127.0.0.1.
- Copy the Markdown summary into your pull request or ticket.
Common problems
- The wrong file type is detected
- Choose Dockerfile or Docker Compose in the type box. Detection looks at the first line that is not a comment: a key such as services: means Compose, anything else (FROM, ARG) means a Dockerfile.
- A finding has a hadolint code I want to ignore
- Add a comment above the line in your real Dockerfile, for example # hadolint ignore=DL3008. This page only reports; it has no ignore list.
- It reports root even though my base image sets a user
- The page cannot see inside the base image. Without a USER line in the last stage it can only say the Dockerfile does not set one.