We love alpine for its size and ubuntu for its familiarity. But in production, why does your Node.js application need curl, bash, or apt-get?
Every extra binary in your container is a potential tool for an attacker if they compromise your application. If they break in, don't hand them a toolbox.
"Distroless" images are ultra-minimal. They contain only your application and its direct runtime dependencies (like libc or a JVM).
What makes them secure?
If you found this helpful, please like and share to support the content!
Always curious to understand the concept, learning by breaking and fixing, and passionate about sharing knowledge with the community.Get in touch with me→
sh or bash into them. If an attacker gets in, they can't run commands.apt, apk, or yum to install malicious software at runtime.Since Distroless images have no build tools, you must use a multi-stage Dockerfile.
# Stage 1: The Builder (Heavy Image)
FROM golang:1.23 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp main.go
# Stage 2: The Runtime (Secure Distroless Image)
# This image has NO shell and NO package manager
FROM gcr.io/distroless/static-debian12
COPY --from=builder /app/myapp /myapp
CMD ["/myapp"]💡 Pro-Architect Tip: The Debugging Dilemma The biggest blocker to adopting Distroless is developers asking: "How do I debug it if I can't docker exec -it /bin/bash?"
You don't exec into it. You attach a debug container to it. Since Kubernetes v1.23, use Ephemeral Debug Containers: kubectl debug -it my-distroless-pod --image=busybox --target=my-app-container This temporarily injects a busybox alongside your running app so you can run ps, ls, and troubleshoot network issues without bloating the production image.


