whalint
A Dockerfile linter written in Go.
Pronounced like whale and lint squashed together. The name comes from the Docker logo looking like a whale, btw.
Philosophy
whalint is narrow and principled on purpose. It only flags things that are silent and consequential: misconfigurations Docker's own build process won't catch, but that lead to real security or uptime problems down the line. Things Docker already errors on, or things that are just style preferences, are out of scope. The goal is a small set of checks worth actually trusting, not a giant list that buries real findings in noise.
Installation
go install github.com/Opulent0/whale-lint/cmd/whalint@latest
Usage
whalint <dockerfile>
whalint --help
Output is a JSON report grouped by finding type (keyword-scoped, stage-scoped, and global/whole-file findings), each with a severity, a message, and the offending instruction's position in the file.
Severity scale
| Severity |
Meaning |
| Suggestion |
Purely a maintenance/clarity issue, no functional or security impact |
| Warning |
Will likely cause a problem eventually, but isn't broken right now |
| Problem |
A real, weakened security or operational posture |
| Critical |
Already broken, no additional vulnerability required |
Rules
| Rule |
Scope |
Severity |
Checks for |
NoLatestTag |
Keyword (FROM) |
Warning |
FROM instructions with no tag, or an explicit :latest tag |
SecretsInInstruction |
Keyword (ENV, ARG) |
Critical |
Hardcoded credentials, both by variable name (e.g. PASSWORD, API_KEY) and by value format (AWS keys, GitHub tokens, Slack tokens, Stripe keys, Google API keys, JWTs, private key headers) |
RanAsRoot |
Stage (final stage only) |
Problem |
Final build stage with no USER set, or explicitly set to root/0 |
NoHealthCheck |
Stage (final stage only) |
Warning / Problem |
Final build stage missing a HEALTHCHECK (Warning), or explicitly disabling one via HEALTHCHECK NONE (Problem) |
InstallAcrossRuns |
Stage |
Warning |
Package manager update and install/add split across separate RUN instructions (apt/apt-get, apk), which can silently install against a stale cached package index |
BuildStages (unused stage detection) |
Global |
Suggestion |
Build stages declared with AS <name> that never get referenced by a later stage or COPY --from= |
License
Licensed under GPLv3. See LICENSE for the full text.
Contributing
See CONTRIBUTING for the full text.