Skip to main content...
Docker
20 min

Day 37: Image optimization: distroless, layer caching

Making images small and safe

A smaller image pulls faster, scans faster, and — critically — has a smaller attack surface. Distroless base images ship only your application and its runtime dependencies, deliberately omitting a shell, package manager, or any other tool an attacker could use after a compromise.

A distroless final stage
FROM gcr.io/distroless/nodejs20-debian12
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
CMD ["dist/index.js"]

This connects straight to Phase 26 (OWASP) and Phase 11 (K8s Security)

If an attacker exploits your app, distroless means there's no shell for them to pivot with — kubectl exec into a distroless container won't give you a shell either, which is a feature, not a limitation.

Layer caching strategy

  • Order instructions from least-frequently-changing to most-frequently-changing
  • Combine related RUN commands to avoid unnecessary intermediate layers
  • Use a .dockerignore to keep node_modules/.git out of the build context entirely

Key terms

Distroless image
A minimal base image with only the app and its runtime deps — no shell, package manager, or extra tools.
.dockerignore
Excludes files from the build context, keeping builds fast and images free of unwanted files.

Phase 5 capstone: containerize the full stack

Containerize a NestJS API, a Next.js frontend, PostgreSQL, Redis, and RabbitMQ — one Dockerfile per app service (multi-stage, distroless or -slim final stage), one docker-compose.yml wiring them together. Target: your API image under 150MB. Check with docker images and iterate on layer ordering and base image choice until you hit it.

Why can't you docker exec into a shell inside a distroless container, and why is that good?

We use cookies

We use cookies to enhance your browsing experience, serve personalized content, and analyze our traffic. By clicking "Accept All", you consent to our use of cookies. Learn more

    Day 37: Image optimization: distroless, layer caching | RBTechIconX