Building an application often requires a full toolchain — compilers, build tools, dev dependencies — but running it usually does not. A naive Dockerfile bakes all those build tools into the final image, producing something large, slow to ship, and with a needlessly wide attack surface. Multi-stage builds solve this elegantly: build in one stage with the full toolchain, then copy only the finished artifacts into a clean, minimal final stage.
A multi-stage Dockerfile has multiple FROM instructions, each starting a new stage. An early stage installs build tools and compiles or bundles the application; the final stage starts from a slim base and copies just the built output from the earlier stage with COPY --from. The build tools and intermediate files never make it into the final image, which can be dramatically smaller.
This lesson covers how multi-stage builds work, why they produce lean and more secure production images, and the patterns for using them across compiled and interpreted languages. They are the standard technique for production Docker images and a major step up from single-stage builds in size, security, and clarity.