If you want to know what is docker multistage build, and how to do one, you are in the right place. With no fuss, you will learn how to do your docker multistage build in 5 minutes, and why you may want to do so. Let’s start.
Docker Multistage Build
What is Docker Multistage Build?
Docker multistage build is an approach to build docker images. Since you are looking for multistage builds, I assume you are familiar with docker already. In short, with docker you define the configuration of a container. Through several commands like FROM
, RUN
, and COPY
, you prepare the configuration of a container by installing modules, files and more.
This is done when the container image is built, that is created for the first time, so that every container that is generated from that image has always the same identical configuration. So far so good, old plain docker. Now, let’s introduce docker multistage build.
Having a docker multistage build means you build your image of a container in an environment, and then you copy parts of it in a different environment. You can do this multiple times, chaining multiple steps.
For example, you may want to prepare all your files and build your binary files into an Ubuntu system, but then release an image which is based on Alpine Linux. No problem, with docker multistage build you can do just that.
Why Docker Multistage Build?
Why bothering with a docker multistage build when you could just simply build and deploy from a single environment? Well, in most cases you cannot do that. There are circumstances where a library you need to build your image is not available on the OS version you want to use in your production systems.
Yet, this problem of compatibility is not as common. The real reasons behind a docker multistage build are security and efficiency.
Security because in the end you copy your binary files, and only your binary files, into the final environment, reducing the surface of attacks (that is, the potential features that a hacker might exploit).
Efficiency because in this way you can ship a more lightweight version of the system, which will save a significant amount of RAM, especially when operating at scale with many containers. If you save 100MB per container, as soon as you spin 10 containers you would have saved 1GB of RAM. Not bad.
How to do a Docker Multistage Build in 5 minutes
To do a docker multistage build, you simply have to use one or more FROM
statement in your dockerfile. Each new FROM
statement indicates that a new step is starting. You should also pair the FROM
statement with AS
so that you can give a name to each step, you will need it later.
Then, you can run all the normal commands in each step. Additionally, for the COPY command you have the –from which allows you to copy data from a previous stage, rather than from the directory where you are building the container.
In this way, you can build on a stage, have the files there, and then copy them from a stage to the next. That is the whole purpose of docker multistage build.
An Example of Docker Multistage Build
This quick example will show you how a docker multistage build is created. It is just a simple docker file with two FROM
statements. You could potentially have even more than two.
In this example, we are preparing an app which is based on Node.js and we try to pack it as small as possible, this is why we build it in a node image and then finalize it in an alpine image.
# We start building in a node image
# we name this stage "build"
FROM node:16.13-alpine AS build
# Set working directory
WORKDIR /usr/src/app
# We copy the files and folders we need
# Here we are copy from the build folder into the
# first stage (build)
COPY package*.json ./
COPY node_modules ./node_modules
COPY dist ./dist
# Run this command to remove unnecessary dependencies
RUN npm prune --production
# Now we create another stage, based on alpine
# We do this because this image is much lighter than the
# previous one. Since it is the last stage, no need to
# give it a name
FROM alpine:3.15
# We set the working directory
WORKDIR /usr/src/app
# We copy files from the build stage into this stage
# Note the --from=build parameter
COPY --from=build /usr/src/app/dist .
COPY --from=build /usr/src/app/node_modules ./node_modules
# Run final commands and expose form the last stage
RUN apk add --update nodejs=16.14.0-r0 --no-cache
EXPOSE 80
CMD ["node", "index.js"]
Docker Multistage Build in Summary
If you are in a hurry (TL;DR) and want to build a docker multistage build, all you need to do is the following:
- Create a simple docker file, but use multiple
FROM
statement - Each FROM statement is a stage, you can name stage by appending
AS <stage name>
toFROM
- When copying files, you can use
--from=<stage name>
parameter to copy files from a previous stage to the next
This is it. As simple as that. If you need more info on Docker, start on this easy tutorial for beginners.