Minimus images come in pairs — the fully distroless image with the smallest attack surface and a dev variant that includes more developer-relevant tools such as package managers, a shell, and more. When you build an app using a multi-stage build, you can take advantage of an image pair to create a more secure final result. In the Dockerfile, you can use the dev image in the builder stage and switch to the production image for the final stage. This way, the build process can discard all the unnecessary tools and produce a cleaner, more minimal and secure artifact.
If your app can run on a runtime base after it’s compiled, you can make the app even smaller and more secure. Go (golang) is a great example. See our article on how to use a runtime base.

Examples

Minimus images are often used in multi-stage builds. Below are a list of recommended tutorials to help you get started:

Advantages of a multi-stage build

Using a different base image for the builder stage and the runtime stage has several advantages:
  • The dev image contains more packages and is therefore more likely to contain more vulnerabilities. For example, we can see that the Python production image has fewer vulnerabilities than the Python dev image. This behavior is consistent across all images, where many times the production image is completely free of vulnerabilities but the dev image might have a few. Compare Vulnerabilities
  • When building an app, there is no advantage to including dev packages that increase the attack surface and are not required to run the app. It is preferable to build the application in stages and reduce the final image in size and attack surface. As a result, the final image will have a small attack surface and fewer vulnerabilities, if any.

    Just to get a sense of the size differences, the compressed size of the python image is just over 22 MB - compared to 218 MB for the python dev image. Similarly, the SBOM for the Python production image lists 23 packages while the Python dev image lists 73 packages.
    python:3.13.5python:3.13.5-dev
    Compressed size22 MB218 MB
    SBOM packages2373

When to use a multi-stage build

Basically, you should use a multi-stage build whenever the opportunity presents itself.
  • Any compiled or interpreted language is a good candidate for a multi-stage build. This includes (but is not limited to): Python, NodeJS, Rust, PHP, Ruby, etc.
  • Go is a special case as you can run the compiled binary on a minimal runtime base. Learn how to run a Go app on a runtime base
  • Some images come in building pairs that have different names. For example: