Dockerfile Hardening Checklist
A do-this-now checklist to turn a typical Dockerfile into a small, secure, non-root, multi-stage production image, with a worked before/after and a .dockerignore starter.
📄 Product Preview
Try the interactive reader and demo tools below, or get the full product with all content unlocked.
📖 Interactive Reader (Free Preview) 📦 Download Free Sample📁 File Structure 6 files
📖 Documentation Preview README excerpt
Dockerfile Hardening Checklist
A focused, do-this-now checklist for turning a typical Dockerfile into a small,
secure, production-grade image — plus a fully worked before/after and a .dockerignore
starter. Cheap, fast, and instantly verifiable: the kind of task an agent should
just apply.
The checklist (apply top to bottom)
- [ ] Pin the base image by digest, not a floating tag.
FROM node:20-slim→
FROM node:20-slim@sha256:.... Reproducible + tamper-evident.
- [ ] Use a slim/distroless base.
-slim,-alpine, orgcr.io/distroless. - [ ] Multi-stage build. Compile/build in one stage, copy only artifacts into a
minimal runtime stage. Keeps build tools out of the shipped image.
- [ ] Run as a non-root user. Create a user;
USER app. Never run as root. - [ ] Drop the build context. A
.dockerignoreso secrets,.git,.env,
node_modules, and CI files never enter the image.
- [ ] No secrets in layers. Never
COPY .envorARG/ENVa secret — it
persists in image history. Use build secrets / runtime env.
- [ ] Install only what you need, then clean caches in the SAME layer
(apt-get ... && rm -rf /var/lib/apt/lists/*).
- [ ] Copy dependency manifests first, install, THEN copy source — maximizes
layer-cache reuse.
- [ ] Set
WORKDIR, notcd. Pin file ownership with--chown. - [ ] Add a
HEALTHCHECK. - [ ] Read-only root filesystem at runtime (
--read-only+ tmpfs) where possible. - [ ] Scan the final image (
trivy image,docker scout) in CI; fail on HIGH. - [ ] Set a specific
CMD(exec form,["node","server.js"]), not shell form.
What's inside
Dockerfile.before— a common, insecure Dockerfile (root, fat base, secrets leak).Dockerfile.after— the hardened, multi-stage, non-root version of the same app..dockerignore— a sensible starter that keeps secrets and cruft out.CHECKLIST.md— the checklist above as a standalone file to drop in your repo.
Requirements
Docker. That's it.
License
MIT.
📄 Content Sample CHECKLIST.md
Dockerfile Hardening — drop-in checklist
- [ ] Base image pinned by digest (
@sha256:...) - [ ] Slim/distroless base
- [ ] Multi-stage build (build tools not shipped)
- [ ] Runs as a non-root
USER - [ ]
.dockerignoreexcludes secrets, .git, node_modules, CI - [ ] No secrets in ARG/ENV/COPY (not in image history)
- [ ] Package manager caches cleaned in the same RUN layer
- [ ] Manifests copied before source (cache-friendly ordering)
- [ ]
--chownon copied files; explicitWORKDIR - [ ]
HEALTHCHECKpresent - [ ] Runtime read-only rootfs where possible
- [ ] Image scanned in CI (trivy/scout), fails on HIGH
- [ ]
CMDin exec form, specific entrypoint