Urgent.News

What's breaking now, across thousands of outlets.

Tech

Multi-stage builds in Docker: smaller, cleaner images

There's a particular kind of waste that happens in Docker images and that everyone accepts as normal until someone points it out: shipping the compiler to production. You need the Go toolchain to build your binary. You don't need it to run it. You need TypeScript, all your dev dependencies, and a working tsc setup to compile your app. You don't need any of that once the JavaScript exists. And…

Docker images often contain unnecessary components, leading to larger image sizes. This is particularly problematic in single-stage Dockerfiles where the entire toolchain and dependencies are included, even though they are not needed during runtime. Multi-stage builds in Docker address this issue by allowing multiple environments to build an application, then only retaining what's necessary for runtime. This results in smaller, more efficient images.

For example, a Go application using a single-stage Dockerfile might include the entire Go compiler, toolchain, and Debian system libraries in the final image, totaling 823MB. However, once the compiled binary is executed, none of this toolchain is required. By using multi-stage builds, the image size can be reduced to just 11MB, as the unnecessary components are removed.

The process involves defining multiple stages within a single Dockerfile. Each stage starts with its own isolated filesystem, and files can be copied from one stage to another using the `COPY --from=stage` instruction. The final stage defines the image that will be pushed, pulled, and deployed. The builder stage uses the Go toolchain to compile the application, while the final stage starts from a minimal base (scratch) and only includes the compiled binary, resulting in a much smaller image size.

The same principle applies to JavaScript and TypeScript projects. By using multi-stage builds, you can keep development dependencies out of the final image and exclude TypeScript source files, which are only needed during compilation.

To implement multi-stage builds, you can include both the build and production stages in a single Dockerfile. The builder stage compiles the application, while the production stage uses a minimal base (scratch) and only includes the compiled output. This results in a smaller final image size, such as 198MB compared to 687MB for a single-stage build.

Furthermore, multi-stage builds allow for multiple targets in a single Dockerfile, making it easier to manage different development environments. For instance, you can have separate stages for development, testing, and production, each with their own specific requirements. This approach promotes a clean, efficient, and maintainable workflow when building Docker images.

Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.

Read the original at dev.to →

More in Tech

More from Wednesday 26 August →