dockerfile-smells-and-hardeninglisted
Install: claude install-skill ClaudeRegistry/marketplace
# Dockerfile Smells and Hardening
## Purpose
A consistent set of Dockerfile anti-patterns and their fixes, so container reviews produce smaller, safer, cache-friendly images the same way every time. This is container-build domain knowledge, the specific smells and the reasons they matter, not generic Docker syntax.
## Smell catalog
| Smell | Why it hurts | Fix |
|-------|--------------|-----|
| Runs as `root` (no `USER`) | container escape = host root; violates PSS/most policies | add `USER <uid>` (numeric, non-root) |
| `latest` / unpinned base tag | non-reproducible; silent base drift; supply-chain risk | pin `FROM img@sha256:<digest>` |
| Single-stage build | ships compilers, headers, build deps in runtime image | multi-stage: build → slim runtime |
| `COPY . .` before dep install | any source edit busts the dependency cache layer | copy manifests, install, *then* copy source |
| Secrets baked in a layer | recoverable from image history forever | `RUN --mount=type=secret`; never `ENV TOKEN=` |
| `apt-get` with no cleanup | apt lists/caches bloat the layer | `--no-install-recommends` + `rm -rf /var/lib/apt/lists/*` in the same `RUN` |
| Missing `.dockerignore` | huge context; `.git`/secrets sent to daemon | add `.dockerignore` |
| No `HEALTHCHECK` | orchestrator can't detect a wedged process | add `HEALTHCHECK` where the app exposes a check |
| `ADD` for local files / remote URLs | silent auto-extract, unverified downloads | use `COPY`; fetch with verified checksums |
|