container-image-hardeninglisted
Install: claude install-skill omonuj/claude-skills
# container-image-hardening
A careless Dockerfile ships a 1.2GB image running as root with the whole build toolchain and your `.git` history baked in. This skill builds the opposite: a small image with only the runtime, a non-root user, pinned bases, and fast cache-friendly builds. Small is not just cheaper — a smaller image has fewer packages, which means fewer CVEs and less attack surface.
## Use when
- Writing or fixing a Dockerfile.
- Images are huge, slow to build, or rebuild fully on every code change.
- A container scan flags CVEs from base-image packages you don't use.
## Multi-stage: build fat, ship thin
Separate the *build* environment from the *runtime*. Compile/install with the full toolchain in a builder stage, then copy only the built artifact into a minimal final stage. The final image never contains compilers, dev headers, or package caches.
```dockerfile
# builder — has the toolchain
FROM node:20.11-bookworm-slim AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci # cached unless lockfile changes
COPY . .
RUN npm run build && npm prune --omit=dev
# runtime — minimal, non-root
FROM gcr.io/distroless/nodejs20-debian12 AS runtime
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
USER nonroot
EXPOSE 3000
CMD ["dist/main.js"]
```
## Layer caching order (build speed)
Docker caches layers top-down and invalidates everything after the first changed layer. Order from