Docker Intermediate: Images, Networks and Compose
Multi-Stage Builds and Small Images
In this lesson you will
- Explain why smaller images are better
- Write a multi-stage Dockerfile
- Use .dockerignore to keep the build context small
Introduction
To build an app you often need compilers, test tools and many files. To run it you need very little. If you ship the whole build environment, your image is large, slow to pull and full of things attackers could use.
The simple explanation
A multi-stage build uses one stage to build your app and a second, clean stage that holds only the result.
An example
A website built with Node, served by nginx:
Dockerfile
# Stage 1: build
FROM node:22 AS build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build
# Stage 2: serve
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 80AS buildnames the first stage.COPY --from=buildtakes only the finished files from it.- The final image contains nginx and your static files. Node,
node_modulesand your source code are not in it.
Build it as normal with docker build -t my-site .. A final image of tens of megabytes instead of a gigabyte is common.
Quick quiz
What is the main benefit of a multi-stage build?
Other ways to shrink images
- Choose a small base such as
-slimoralpine, and test your app on it. - Combine related commands and clean up in the same layer, for example installing packages and removing the package cache in one
RUN. - Install only production dependencies in the final image.
- Do not copy files you do not need.
.dockerignore
When you run docker build ., the folder is sent to Docker as the build context. A .dockerignore file excludes files, which speeds up the build and avoids leaking secrets:
node_modules
.git
.env
*.log
distBuild targets
You can stop at an earlier stage, for example to run tests:
Terminal
docker build --target build -t my-site:test .Try it yourself
Take one of your projects with a build step and write a two-stage Dockerfile. Compare the size of the single-stage and multi-stage images with docker image ls.
Summary
- Multi-stage builds compile in one stage and copy only the output into a small final image.
- Smaller images pull faster and expose less to attackers.
- Use
.dockerignoreto keep the build context small and secrets out.
Lesson complete
+20 XP
Nice work. Keep going while it is fresh.
Sources and further reading