3.3.1.4 Distroless Base Images
A focused guide to Distroless Base Images, connecting core concepts with practical Docker and container operations.
Distroless base images strip away nearly everything beyond what an application's compiled runtime actually needs to execute — no package manager, no shell, no general-purpose utilities — minimizing both image size and the attack surface available to anyone who might compromise the running container.
What "Distroless" Removes
A typical distroless image excludes shells, package managers, and common command-line utilities, including only the language runtime (if needed) and the minimal set of shared libraries an application actually depends on.
FROM gcr.io/distroless/python3
COPY app.py /app.py
CMD ["/app.py"]
Unlike a typical base image, there is no shell available inside a container built from this image, which means commands relying on shell features simply cannot run.
Why Removing the Shell Matters for Security
A container without a shell or general-purpose utilities significantly limits what an attacker could do even after successfully exploiting a vulnerability in the running application, since common post-exploitation techniques often rely on a shell or standard tools being available.
docker exec myapp sh
Run against a distroless-based container, this command fails outright, since no shell exists inside the image to execute.
Tradeoffs During Debugging
The same minimalism that improves security makes interactive debugging inside a running container difficult or impossible, which is a deliberate tradeoff — distroless images are intended for production, with debugging typically performed against a separate, fuller image built from the same source.
FROM gcr.io/distroless/python3:debug
Some distroless image variants include a minimal busybox shell specifically for debugging purposes, intended to be used temporarily rather than in actual production deployments.
Combining Distroless With Multi-Stage Builds
Distroless images are typically used as the final stage of a multi-stage build, with an earlier, fuller-featured stage handling compilation or dependency installation before only the necessary output is copied into the minimal final image.
FROM python:3.12 AS build
RUN pip install --target=/app/deps -r requirements.txt
FROM gcr.io/distroless/python3
COPY --from=build /app/deps /app/deps
COPY app.py /app.py
CMD ["/app.py"]
Why Distroless Base Images Matter
Distroless images represent a deliberate tradeoff favoring minimal attack surface and image size over interactive convenience, making them especially well suited to production deployments where the running application is the only thing that should ever need to execute inside the container.