Distroless images¶
Distroless images are minimal container images that contain only the application and its runtime dependencies, without including package managers, shells, or other standard Linux distribution utilities.
Key Benefits¶
- Reduced Attack Surface: No shell or package manager means fewer vulnerabilities to exploit
- Smaller Image Size: Only essential runtime components are included
- Improved Security: Minimizes the potential for supply chain attacks
- Better Compliance: Easier to audit and maintain due to fewer components
Common Use Cases¶
- Production deployments where security is critical
- Microservices and cloud-native applications
- Containerized applications that don't require debugging tools in production
Popular Distroless and Minimal Base Images¶
True Distroless Images (No Package Manager)¶
These images do not include package managers in the final image, providing maximum security by eliminating the ability to install additional packages at runtime.
Google Distroless¶
Primarily maintained by Google and available at gcr.io/distroless/.
Key Features:
- No shell or package manager
- Supports multiple runtimes: static binaries, Java, Python, Node.js, .NET
- Based on Debian
Size: ~110MB for multi-stage builds with distroless (vs 848MB without optimization)
Links:
Chainguard Images (Wolfi-based)¶
Built on Wolfi, a Linux distribution designed for cloud workloads with zero known CVEs.
Key Features:
- Uses glibc (not musl like Alpine)
- Constantly rebuilt with latest sources
- Includes SBOMs for every image
- No kernel (container runtime only)
- No package manager in runtime image (apk only during build)
Available at: cgr.dev/chainguard/
Links:
Ubuntu Chiseled¶
Distroless images built from Ubuntu packages using Chisel.
Key Features:
- Uses glibc
- No shell or package manager in final image
- Only minimal required dependencies included
- Carefully sliced packages
Available at: ubuntu/ on Docker Hub
Links:
BusyBox¶
Single compact executable with simplified Linux tools.
Key Features:
- Multiple libc flavors: musl, glibc, uclibc
- Includes basic utilities (file archiving, process manipulation, etc.)
- No package manager
- Extremely minimal
Links:
Scratch¶
Docker's most minimal base - literally empty.
Key Features:
- Contains nothing at all
- Only suitable for static binaries
- Smallest possible image
Links:
Minimal Images with Package Managers¶
These images include package managers, allowing installation of additional packages at runtime. They offer more flexibility but a larger attack surface compared to true distroless images.
Alpine Linux¶
Popular minimal Linux distribution (~5MB base image).
Key Features:
- Uses musl libc (not glibc)
- BusyBox tool suite
- apk package manager included
- Very small size
Considerations:
- Some applications require glibc and won't work with musl
- Performance degradation possible (2x slowdown not uncommon)
- Limited package availability compared to Debian/Ubuntu
Links:
Debian Slim¶
Pared-down Debian with commonly needed tools removed.
Key Features:
- Uses glibc
- apt package manager included
- Good balance between size and functionality
- ~74MB (vs 118MB for full Debian)
Links:
Red Hat UBI Minimal¶
RHEL-based minimal image for enterprise environments.
Key Features:
- Based on RHEL packages
- microdnf package manager (scaled-down DNF)
- Strong security focus and timely updates
- ~92MB on disk, 32MB compressed
Considerations:
- Limited to curated Red Hat packages
- Best for Red Hat ecosystem (OpenShift, RHEL)
- Subscription required for non-UBI packages
Links:
Comparison Summary¶
True Distroless Images (No Runtime Package Manager)¶
| Image | Maintainer | Size | Package Manager | libc | Use Case |
|---|---|---|---|---|---|
| Scratch | Docker | 0 MB | None | None | Static binaries only |
| BusyBox | BusyBox Project | ~5 MB | None | Various | Basic utilities needed |
| Chainguard | Chainguard | ~20-80 MB | None (apk build only) | glibc | Supply chain security |
| Ubuntu Chiseled | Canonical | ~20-50 MB | None | glibc | Ubuntu ecosystem |
| Distroless | ~25-100 MB | None | glibc | Production, high security |
Images with Package Managers¶
| Image | Maintainer | Size | Package Manager | libc | Use Case |
|---|---|---|---|---|---|
| Alpine | Alpine Linux | ~5 MB | apk | musl | General purpose, size-critical |
| Debian Slim | Debian Project | ~74 MB | apt | glibc | More tooling, Debian packages |
| UBI Minimal | Red Hat | ~92 MB | microdnf | glibc | Enterprise/Red Hat ecosystem |
Use Cases for Distroless Images¶
- Pure static binaries - Use scratch (most minimal, zero attack surface)
- Static binaries needing ca-certificates - Using distroless/static variant
- Precompiled Java JAR/WAR files - Using Java runtime variants
- Precompiled Python applications - Using Python runtime variant
- Precompiled Node.js applications - Using Node.js runtime variants
- Precompiled .NET applications - Using .NET runtime variants
- Dynamic binaries requiring glibc - Using base or glibc-dynamic variants
- C/C++ applications - Using cc variant (includes libgcc, libstdc++)
- Go binaries with CGO enabled - Using base variant (includes glibc and SSL libraries)
Specific Distroless Implementations¶
Liberica Runtime Container (BellSoft)¶
Optimized Java runtime containers from BellSoft, available as both JDK and JRE variants.
Available at: bellsoft/liberica-runtime-container
Links:
Amazon Corretto¶
No-cost, production-ready distribution of OpenJDK from Amazon Web Services.
Available at: amazoncorretto
Links:
Multi-Stage Build Pattern¶
Distroless images are typically used in multi-stage builds where dependencies are installed in a full-featured image, then only the application and runtime are copied to the distroless final image:
# Build stage
FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp
# Final stage
FROM gcr.io/distroless/static-debian12
COPY --from=builder /app/myapp /myapp
ENTRYPOINT ["/myapp"]
Important Note on ENTRYPOINT¶
Distroless images without a shell require ENTRYPOINT to be specified in exec form (JSON array), not shell form:
# Correct - exec form
ENTRYPOINT ["/myapp", "--flag"]
# Wrong - shell form (requires /bin/sh)
ENTRYPOINT /myapp --flag