Convert Figma logo to code with AI

GoogleContainerTools logodistroless

🥑 Language focused docker images, minus the operating system.

18,629
1,142
18,629
87

Top Related Projects

68,613

The Moby Project - a collaborative project for the container ecosystem to assemble container-based systems

11,728

CLI tool for spawning and running containers according to the OCI specification

An open and reliable container runtime

Alpine Linux Docker image. Win at minimalism!

A minimal Ubuntu base image modified for Docker-friendliness

1,157

Build OCI images from APK packages directly without Dockerfile

Quick Overview

Distroless is a project by Google that provides minimal container base images with language runtimes and little else. These images are designed to be secure, small, and fast, containing only the essential components needed to run an application, without unnecessary tools or packages.

Pros

  • Significantly reduced container image size, leading to faster deployments and lower storage costs
  • Improved security posture due to minimal attack surface and fewer vulnerabilities
  • Better performance due to reduced overhead from unnecessary components
  • Compliance with best practices for containerized applications

Cons

  • Limited debugging capabilities in production environments due to lack of common tools
  • Potential learning curve for developers accustomed to full-featured base images
  • May require additional steps or custom images for applications with specific dependencies
  • Not suitable for all use cases, particularly those requiring shell access or system utilities

Getting Started

To use Distroless images, simply specify the appropriate base image in your Dockerfile. Here's an example for a Go application:

# Build stage
FROM golang:1.17 as builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o myapp

# Final stage
FROM gcr.io/distroless/static-debian11
COPY --from=builder /app/myapp /
CMD ["/myapp"]

To build and run the container:

docker build -t myapp .
docker run myapp

For other languages and specific use cases, refer to the Distroless documentation on GitHub for the appropriate base image and configuration.

Competitor Comparisons

68,613

The Moby Project - a collaborative project for the container ecosystem to assemble container-based systems

Pros of moby

  • More comprehensive container ecosystem with broader functionality
  • Larger community and extensive documentation
  • Flexible and customizable for various use cases

Cons of moby

  • Larger image size and attack surface
  • More complex setup and configuration
  • Potential for unnecessary components in minimal environments

Code comparison

moby:

FROM debian:buster-slim
RUN apt-get update && apt-get install -y \
    nginx \
    && rm -rf /var/lib/apt/lists/*
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

distroless:

FROM gcr.io/distroless/static-debian10
COPY --from=nginx:1.19.2 /usr/sbin/nginx /usr/sbin/nginx
COPY --from=nginx:1.19.2 /etc/nginx /etc/nginx
EXPOSE 80
CMD ["/usr/sbin/nginx", "-g", "daemon off;"]

Key differences

  • distroless focuses on minimal, secure base images
  • moby provides a full container platform and ecosystem
  • distroless requires more manual configuration but results in smaller, more secure images
  • moby offers easier setup but may include unnecessary components
  • Both projects aim to improve container security and efficiency, but with different approaches
11,728

CLI tool for spawning and running containers according to the OCI specification

Pros of runc

  • More versatile and can be used as a standalone runtime for containers
  • Provides lower-level control over container execution
  • Widely adopted and supported by the Open Container Initiative (OCI)

Cons of runc

  • Requires more configuration and setup compared to distroless
  • May introduce more security risks due to its broader functionality
  • Larger image size and potentially higher resource usage

Code Comparison

runc:

spec, err := loadSpec(context.Background(), specConfig)
if err != nil {
    return err
}
status, err := startContainer(context.Background(), spec, opts)

distroless:

FROM gcr.io/distroless/static-debian11
COPY --from=builder /app/myapp /
CMD ["/myapp"]

Summary

runc is a more flexible and powerful container runtime, offering greater control but requiring more setup. distroless focuses on providing minimal, secure base images for applications, simplifying deployment but with less customization options. The choice between them depends on specific project requirements and the level of control needed over container execution.

An open and reliable container runtime

Pros of containerd

  • More comprehensive container runtime solution
  • Broader ecosystem support and integration
  • Active development with frequent updates

Cons of containerd

  • Larger footprint and complexity
  • Steeper learning curve for beginners
  • May include unnecessary features for simple use cases

Code Comparison

distroless:

FROM gcr.io/distroless/static-debian11
COPY myapp /
CMD ["/myapp"]

containerd:

import (
    "github.com/containerd/containerd"
    "github.com/containerd/containerd/cio"
)

client, _ := containerd.New("/run/containerd/containerd.sock")
container, _ := client.NewContainer(ctx, "mycontainer", spec)
task, _ := container.NewTask(ctx, cio.NewCreator(cio.WithStdio))

Summary

containerd is a more comprehensive container runtime solution with broader ecosystem support, while distroless focuses on providing minimal, secure base images. containerd offers more features and flexibility but comes with increased complexity. distroless is simpler to use and results in smaller container images but may lack some advanced functionalities. The choice between them depends on specific project requirements and the level of control needed over the container lifecycle.

Alpine Linux Docker image. Win at minimalism!

Pros of docker-alpine

  • Includes a package manager (apk), allowing for easy installation of additional tools
  • Provides a more familiar Linux environment for debugging and troubleshooting
  • Smaller base image size compared to most other Linux distributions

Cons of docker-alpine

  • Larger image size compared to distroless containers
  • Potential security vulnerabilities due to included shell and utilities
  • Requires more maintenance and updates to keep the base image secure

Code Comparison

docker-alpine:

FROM alpine:3.14
RUN apk add --no-cache python3
COPY app.py /app/
CMD ["python3", "/app/app.py"]

distroless:

FROM gcr.io/distroless/python3
COPY app.py /app/
CMD ["/app/app.py"]

The docker-alpine example includes a package manager to install Python, while distroless comes with Python pre-installed. The distroless Dockerfile is simpler and doesn't require additional package installation steps.

A minimal Ubuntu base image modified for Docker-friendliness

Pros of baseimage-docker

  • Includes init system and process management, suitable for multi-process containers
  • Provides a more complete Ubuntu-based environment with common tools and utilities
  • Easier to use for developers familiar with traditional Linux environments

Cons of baseimage-docker

  • Larger image size due to included utilities and full OS components
  • Potential security risks from unnecessary packages and services
  • Higher maintenance overhead with regular updates and patches

Code Comparison

baseimage-docker:

FROM phusion/baseimage:focal-1.2.0
RUN apt-get update && apt-get install -y python3
CMD ["/sbin/my_init"]

distroless:

FROM gcr.io/distroless/python3
COPY --from=build /app /app
CMD ["/app/myapp"]

Key Differences

distroless focuses on minimal, security-oriented images with only necessary components, while baseimage-docker provides a more traditional, feature-rich environment. distroless images are significantly smaller and have a reduced attack surface, but may require more effort to set up for complex applications. baseimage-docker offers easier setup for multi-process applications and familiar Linux tools, at the cost of larger image sizes and potential security concerns.

1,157

Build OCI images from APK packages directly without Dockerfile

Pros of apko

  • More flexible and customizable build process
  • Supports a wider range of base images and package managers
  • Allows for easier integration with existing CI/CD pipelines

Cons of apko

  • Less mature and battle-tested compared to distroless
  • Requires more configuration and setup
  • May have a steeper learning curve for beginners

Code Comparison

apko configuration example:

contents:
  repositories:
    - https://dl-cdn.alpinelinux.org/alpine/edge/main
  packages:
    - alpine-base
    - python3

entrypoint:
  command: /usr/bin/python3

distroless Dockerfile example:

FROM gcr.io/distroless/python3-debian10
COPY . /app
WORKDIR /app
CMD ["python3", "main.py"]

Both projects aim to create minimal, secure container images, but they approach the task differently. apko offers more flexibility and customization options, while distroless provides a more straightforward, opinionated solution. The choice between the two depends on specific project requirements, team expertise, and desired level of control over the build process.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

"Distroless" Container Images.

CI Build Status

"Distroless" images contain only your application and its runtime dependencies. They do not contain package managers, shells or any other programs you would expect to find in a standard Linux distribution.

For more information, see this talk (video).

Since March 2023, Distroless images use oci manifests, if you see errors referencing application/vnd.oci.image.manifest.v1+json or application/vnd.oci.image.index.v1+json, update your container tooling (docker, jib, etc) to latest.

Why should I use distroless images?

Restricting what's in your runtime container to precisely what's necessary for your app is a best practice employed by Google and other tech giants that have used containers in production for many years. It improves the signal to noise of scanners (e.g. CVE) and reduces the burden of establishing provenance to just what you need.

Distroless images are very small. The smallest distroless image, gcr.io/distroless/static-debian12, is around 2 MiB. That's about 50% of the size of alpine (~5 MiB), and less than 2% of the size of debian (124 MiB).

How do I use distroless images?

These images are built using bazel, but they can also be used through other Docker image build tooling.

What images are available?

The following images are currently published and updated by the distroless project (see SUPPORT_POLICY for support timelines)

Debian 12

ImageTagsArchitecture Suffixes
gcr.io/distroless/static-debian12latest, nonroot, debug, debug-nonrootamd64, arm64, arm, s390x, ppc64le
gcr.io/distroless/base-debian12latest, nonroot, debug, debug-nonrootamd64, arm64, arm, s390x, ppc64le
gcr.io/distroless/base-nossl-debian12latest, nonroot, debug, debug-nonrootamd64, arm64, arm, s390x, ppc64le
gcr.io/distroless/cc-debian12latest, nonroot, debug, debug-nonrootamd64, arm64, arm, s390x, ppc64le
gcr.io/distroless/python3-debian12latest, nonroot, debug, debug-nonrootamd64, arm64
gcr.io/distroless/java-base-debian12latest, nonroot, debug, debug-nonrootamd64, arm64, s390x, ppc64le
gcr.io/distroless/java17-debian12latest, nonroot, debug, debug-nonrootamd64, arm64, s390x, ppc64le
gcr.io/distroless/java21-debian12latest, nonroot, debug, debug-nonrootamd64, arm64, ppc64le
gcr.io/distroless/nodejs18-debian12latest, nonroot, debug, debug-nonrootamd64, arm64, arm, s390x, ppc64le
gcr.io/distroless/nodejs20-debian12latest, nonroot, debug, debug-nonrootamd64, arm64, arm, s390x, ppc64le
gcr.io/distroless/nodejs22-debian12latest, nonroot, debug, debug-nonrootamd64, arm64, arm, s390x, ppc64le

These images refer to image indexes with references to all supported architectures. Architecture specific images can be directly referenced using an additional architecture suffix on the tag, like gcr.io/distroless/static-debian12:latest-amd64

Any other tags are considered deprecated and are no longer updated

How do I verify distroless images?

All distroless images are signed by cosign with emphemeral keys (keyless) -- this is the only supported mechanism starting November 2023. We recommend verifying any distroless image you use before building your image. You can verify the keyless signature of any distroless image with:

cosign verify $IMAGE_NAME --certificate-oidc-issuer https://accounts.google.com  --certificate-identity keyless@distroless.iam.gserviceaccount.com

Entrypoints

Note that distroless images by default do not contain a shell. That means the Dockerfile ENTRYPOINT command, when defined, must be specified in vector form, to avoid the container runtime prefixing with a shell.

This works:

ENTRYPOINT ["myapp"]

But this does not work:

ENTRYPOINT "myapp"

For the same reasons, if the entrypoint is set to the empty vector, the CMD command should be specified in vector form (see examples below). Note that by default static, base and cc images have the empty vector entrypoint. Images with an included language runtime have a language specific default (see: java, nodejs, python3).

Docker

Docker multi-stage builds make using distroless images easy. Follow these steps to get started:

  • Pick the right base image for your application stack.

  • Write a multi-stage docker file. Note: This requires Docker 17.05 or higher.

    The basic idea is that you'll have one stage to build your application artifacts, and insert them into your runtime distroless image. If you'd like to learn more, please see the documentation on multi-stage builds.

Examples with Docker

Here's a quick example for go:

# Start by building the application.
FROM golang:1.18 as build

WORKDIR /go/src/app
COPY . .

RUN go mod download
RUN CGO_ENABLED=0 go build -o /go/bin/app

# Now copy it into our base image.
FROM gcr.io/distroless/static-debian12
COPY --from=build /go/bin/app /
CMD ["/app"]

You can find other examples here:

To run any example, go to the directory for the language and run

docker build -t myapp .
docker run -t myapp

To run the Node.js Express app node-express and expose the container's ports:

npm install # Install express and its transitive dependencies
docker build -t myexpressapp . # Normal build command
docker run -p 3000:3000 -t myexpressapp

This should expose the Express application to your localhost:3000

Bazel

For full documentation on how to use bazel to generate Container images, see the bazel-contrib/rules_oci repository.

For documentation and example on how to use the go-based debian package manager (current) to generate bazel config, see ./debian_package_manager For documentation and examples on how to use the bazel package manager rules (not used in this repo), see ./package_manager

Examples can be found in this repository in the examples directory.

Examples with Bazel

We have some examples on how to run some common application stacks in the /examples directory. See here for:

See here for examples on how to complete some common tasks in your image:

See here for more information on how these images are built and released.

Base Operating System

Distroless images are based on Debian 12 (bookworm). Images are explicitly tagged with Debian version suffixes (e.g. -debian12). Specifying an image without the distribution will currently select -debian12 images, but that will change in the future to a newer version of Debian. It can be useful to reference the distribution explicitly, to prevent breaking builds when the next Debian version is released.

Operating System Updates for Security Fixes and CVEs

Distroless tracks the upstream Debian releases, using Github actions to automatically generate a pull request when there are updates.

Debug Images

Distroless images are minimal and lack shell access. The :debug image set for each language provides a busybox shell to enter.

For example:

cd examples/python3/

edit the Dockerfile to change the final image to :debug:

FROM gcr.io/distroless/python3-debian12:debug
COPY . /app
WORKDIR /app
CMD ["hello.py", "/etc"]

then build and launch with an shell entrypoint:

$ docker build -t my_debug_image .
$ docker run --entrypoint=sh -ti my_debug_image

/app # ls
BUILD       Dockerfile  hello.py

Note: If the image you are using already has a tag, for example gcr.io/distroless/java17-debian12:nonroot, use the tag debug-<existing tag> instead, for example gcr.io/distroless/java17-debian12:debug-nonroot.

Note: ldd is not installed in the base image as it's a shell script, you can copy it in or download it.

Who uses Distroless?

If your project uses Distroless, send a PR to add your project here!

Community Discussion