MacMusic  |  PcMusic  |  440 Software  |  440 Forums  |  440TV  |  Zicos
image
Search

How to make lightweight Docker images (and keep them slim)

Wednesday February 5, 2025. 10:00 AM , from InfoWorld
It’s a challenge keeping Docker images from bulking up unnecessarily. A single base image, a couple of RUN commands, and before you know it, you’re looking at an image weighing 200 MB or more. Is all that tonnage really necessary?

Odds are you can make the images you build a good deal more svelte with only a little work, and without losing any real functionality. This guide walks through six ways to create slender Docker images and keep them that way.

Start from scratch

The most basic Docker image you can create, scratch, isn’t actually an image but an empty container that you can fill with whatever your application needs. Starting from scratch (or scratch) may seem like the way to create a minimal image, and in many cases, it can be. But this approach comes with a few pitfalls.

First, scratch makes no assumptions at all about what your application needs. If your app consists of a single binary with no dependencies—for instance, a Go application—then the scratch image will work. But the vast majority of applications have some kind of runtime dependency: a linked library, maybe, or perhaps even a certificate.

Don’t assume that just because the application launches and runs, it’s fully functional. Omissions like a missing linked library can ambush you if you’re not testing for their presence. This is a particularly big issue in dynamic languages like Python, where without tests you get no warning something is missing until you need it.

If you’re avoiding starting from scratch because you tried it and ended up with something that didn’t work, don’t assume you need to throw in everything plus the kitchen sink (and countertops) to get it working. You may be able to begin with a runtime designed to start with the minimal requirements for the language or runtime you’re employing.

Use a ‘slim’ runtime image

For many applications written in languages that require a runtime, you can use a “slim” runtime image for the language. These are prebuilt images that contain the bare minimum of what’s needed to launch and run an application written in the given language.

It’s worth saying again that slim images only give you what’s needed to support the runtime itself, not your particular application. For instance, if you have a Python application that needs third-party packages from PyPI, you must add those as part of the image build process (RUN pip install, etc.).

Another good source for slender base images, built for specific use cases, is the Google Distroless Image collection. They’re built on top of stripped-down instances of Debian Linux, run on multiple architectures, and offer included runtimes for Python 3, C-compiled programs, Java (including versions 17 and 21), and Node.js (versions 18, 20, and 22). They don’t contain shells or package managers, so you must configure your Dockerfile’s ENTRYPOINT so it won’t attempt to use a shell (e.g., ENTRYPOINT ['start'] instead of ENTRYPOINT 'start') or supply arguments to the language runtime configured as the default.

Use multi-stage builds

A convenient way to automatically minimize the amount of space used when building is the multi-stage build process. Multi-stage builds use multiple FROM statements in the Dockerfile. Each successive FROM lets you begin with a completely new container image, which you can then populate selectively with artifacts created from the previous FROM build process.

This trick works best when you have, for instance, some kind of software build process as part of the procedure. Much of what’s left over after the build process isn’t needed, so you can discard it and just copy out the needed bits into a new, empty image.

Another very nice feature of multi-stage builds: stages can be named and re-used across the build process. And the resulting images can be saved and re-used, or harvested from selectively, for future projects.

Minimize layers

Each distinct RUN command in your Dockerfile creates a new layer in your image. You’ll want to consolidate as many of those commands as possible when layering in your application’s requirements. You don’t have to try to do this at first; it’s something you can discover incrementally, as you experiment with the best set of RUN instructions to get your container together.

You can also use the third-party docker-squash tool to “squash” together two or more layers in an image. Or, again, you can use the multi-stage process to “scrape” a given build stage to only what’s needed, then populate a new, empty stage with that.

Use.dockerignore

A.dockerignore file, like its cousin in Git (.gitignore), lets you screen out files and directories from the build process. In some ways this is the opposite approach from a multi-stage build: instead of cherry-picking what to include from an existing image, you’re describing what to leave out of an image that is yet to be built.

Anything ephemeral or irrelevant to the runtime is a good candidate for being filtered out: Git repositories, temporary directories, build artifacts, downloaded archives (from which other things are unpacked), and so on. This way, you don’t have to clean the build directory ahead of time, which risks losing the advantage you get from caches or local copies. You can just omit them from the build.

You can get pretty granular with.dockerignore, in the same way you can with.gitignore, so you can use it to do things like ignore all files in a directory except a particular one. You may also find it useful to programmatically generate.dockerignore as part of the build process if you’re dealing with a complex and changing set of possible filters.

Use tooling to inspect and alter existing images

Various tools exist for inspecting existing Docker images and seeing what’s there, or taking an image and minifying it by runtime analysis.

The dive tool lets you take a Docker image and break down its contents layer by layer. For each layer you can see the changes made from the previous layer, and get an estimate of how efficient (or inefficient) each layer’s space usage is. If an image has a lot of wasted space or redundancies, dive can reveal that quickly.

A more powerful tool, Slim, now a CNCF Sandbox project, performs runtime analysis on a container to determine what’s being used and what’s not. Its creators boast that Slim can reduce images by orders of magnitude in size, although your mileage will vary. But it’s worth experimenting with for the xray function alone, which can generate a reverse-engineered Dockerfile from a container. That’s a handy way to rethink how a container is assembled without needing to see its sources.
https://www.infoworld.com/article/3811495/how-to-make-lightweight-docker-images-and-keep-them-slim.h

Related News

News copyright owned by their original publishers | Copyright © 2004 - 2025 Zicos / 440Network
Current Date
Feb, Wed 5 - 16:48 CET