Distroless Container Images
repository·main·Indexed 12 days ago
https://github.com/googlecontainertools/distrolessMinimal container images containing only an application and its runtime dependencies, excluding shells and package managers to improve security and reduce image size. Provides base images for static binaries, C++, Rust, Java (OpenJDK 17, 21, 25), Node.js (v22, v24, v26), and Python 3.13, with support for Debian 12 and 13.
What's inside Distroless
- Distroless images contain only your application and its runtime dependencies. They do not include package managers, shells, or other standard Linux distribution programs. This minimalism improves security by reducing the attack surface and making vulnerability (CVE) scanning more efficient.
Understand the `dpkg` metadata structure in Distroless images
mainGoogle Distroless Debian-based images use a non-standard
dpkgmetadata structure to facilitate CVE scanning and package analysis while minimizing image footprint. Unlike traditional Debian images that use a single/var/lib/dpkg/statusfile and an/var/lib/dpkg/info/directory, Distroless images consolidate all package information into the/var/lib/dpkg/status.d/directory.To identify installed packages and their versions, tools should scan
/var/lib/dpkg/status.d/instead of looking for the standard/var/lib/dpkg/statusfile./var/lib/dpkg/ └── status.d/ ├── <package> └── <package>.md5sumsChoose the right distroless base image
mainDistroless provides three primary base images depending on your application's requirements for libc and SSL support. Choose based on your language and compilation strategy:
gcr.io/distroless/static: For statically compiled applications (e.g., Go) that do not require libc. Includesca-certificates,/etc/passwd(root),/tmp, andtzdata.gcr.io/distroless/base-nossl: For applications that require libc but do not need libssl. Includes everything instaticplusglibc.gcr.io/distroless/base: For most other applications, including Go apps that require libc/cgo. Includes everything instatic,glibc, andlibssl(pluszlibandlibzstdfor Debian 13+).
Important Note on OpenSSL: Debian 13+ base images do not include OpenSSL legacy algorithms. If your application requires them, you must add
openssl-legacy-providermanually.Configure ENTRYPOINT and CMD for Distroless
mainBecause distroless images do not contain a shell, you must use the
vector(exec) form forENTRYPOINTandCMDin your Dockerfile. Using the shell form will cause the container to fail because the runtime will attempt to prefix the command with/bin/sh.# Correct: uses vector form ENTRYPOINT ["myapp"] # Incorrect: will fail (attempts to use shell) ENTRYPOINT "myapp"Handle library discovery with `ctypes.util.find_library()`
mainThe image includes a pre-generated
ld.so.cacheto support calls toctypes.util.find_library().Important: If you modify the image by adding new shared libraries (e.g., via a multi-stage build), these new libraries will not be found by
ctypesunless you runldconfigto refresh the cache.Use the `gcr.io/distroless/cc` image for C++ or Rust applications
mainThe
gcr.io/distroless/ccimage is a minimal Linux runtime based onglibc. It is designed for "mostly-statically compiled" languages such as Rust, D, or C++ that require specific shared libraries not present in the standardbaseimage.This image includes everything found in the distroless/base image, plus:
libgcc1and its dependencies.
To use this image, you must copy your compiled application binary into the image and specify the correct
CMD(command) to execute your application.# Example Dockerfile usage FROM gcr.io/distroless/cc COPY my-compiled-app /my-compiled-app CMD ["/my-compiled-app"]Add a new JAVA version to distroless
mainTo support a new OpenJDK version within the distroless repository, follow these steps:
- Update
ADOPTIUM_DEB_PER_DISTROinjava/BUILDwith the new version. - Update
JAVA_MAJOR_VERSIONSinjava/config.bzl. - Add two YAML files to the
java/testdatafolder to prepare the necessary test data (refer to existing files in that directory for the required format). - Verify the changes by running the Bazel build command for the java directory.
bazel build //java:...- Update
Use the `gcr.io/distroless/python3` image
mainThe
gcr.io/distroless/python3image provides a minimal Linux runtime containing Python 3.13 and its dependencies. It does not include a shell.The image's entrypoint is set to
python. To run a script, you must provide the path to your.pyfile in theCMDinstruction of your Dockerfile.FROM gcr.io/distroless/python3 COPY my_script.py /app/my_script.py CMD ["/app/my_script.py"]Ensure compatibility in multi-stage builds
mainTo prevent ABI-related errors when using distroless Python images in multi-stage builds, use a compatible build image.
For example, if targeting
python3-debian13, usepython:3.13-slim-trixieas your build stage.Additionally, because the distroless Python path is
/usr/bin/python, ensure your build environment matches this path to avoid broken internal links in virtual environments. If your build image uses a different path (like/usr/local/bin/python), create a symlink during the build stage:# Example symlink fix in build stage RUN ln -s /usr/local/bin/python /usr/bin/pythonImplement package scanning for Distroless tool authors
mainWhen developing security scanners, vulnerability analyzers, or package management tools intended to run against Distroless images, follow these implementation guidelines:
- Scan Directory: Target
/var/lib/dpkg/status.d/to find installed packages. - Retrieve Metadata: Read the
<package>file for version and dependency details. - Retrieve File Lists/Checksums: Use the
<package>.md5sumsfile to identify which files belong to a package and verify their integrity. - Avoid Standard Paths: Do not attempt to access or rely on the following paths, as they are intentionally omitted:
/var/lib/dpkg/status/var/lib/dpkg/info/<package>.list/var/lib/dpkg/info/<package>.md5sums- Any other files in
/var/lib/dpkg/info/
- Scan Directory: Target
Use `gcr.io/distroless/java` images
mainThe
gcr.io/distroless/javaimages provide a minimal Linux runtime based on OpenJDK.Entrypoint Behavior: The image's entrypoint is configured to execute the equivalent of
java -jar. Consequently, when using this image, you must provide the path to your application's JAR file via theCMDinstruction in your Dockerfile or as an argument to your container runtime.Available Versions: Depending on the specific tag used, the image includes Temurin OpenJDK versions:
gcr.io/distroless/java17-debian13(OpenJDK 17)gcr.io/distroless/java21-debian13(OpenJDK 21)gcr.io/distroless/java25-debian13(OpenJDK 25)
# Example usage in a Dockerfile FROM gcr.io/distroless/java21-debian13 COPY my-app.jar /app/my-app.jar CMD ["/app/my-app.jar"]Use distroless Node.js images
mainDistroless Node.js images provide a minimal Linux runtime containing only the necessary dependencies for Node.js. The entrypoint is pre-configured to
node, meaning you must provide the path to your application's entrypoint file (e.g.,app.js) using theCMDinstruction in your Dockerfile.# Example usage pattern FROM gcr.io/distroless/nodejs22-debian13 COPY app.js /app/app.js CMD ["/app/app.js"]