It is very important to build efficient docker images using Dockerfile whenever pushing out images into production. We need images as small as possible in production for faster downloads, lesser surface attacks.
In this article we'll cover different points:
- Life without Multi-stage Build
- Image Optimization
I have talked about dockerfile and how to build docker image for an application a fair bit in the past. As we build image for our angular application named as angularapp in the last article when we build a basic Dockerfile, like the following,
we end up with an image that size is astonishingly high which is 1.28GB.
We can’t ship the image of this size to production because of slower downloads. It takes longer than usual to download this image over the network.
Another problem is the larger surface area which is prone to attacks. We included npm dependencies and the entire Angular CLI library in the image which are unnecessary in the final image.
After facing all these difficulties, we came with different solutions through we can optimize our images:
In Docker Hub (the public Docker repository) there are several images available for download, each with different characteristics and sizes.
Normally, images based on Alpine extremely small in size compared to those based on other Linux distributions, such as Ubuntu. So to optimize our image we'll use alpine image as a base image.
Basically Multi-stage dockerfile is use to minimize the size of the final container, improve run time performance, allow for better organization of Docker commands and files.
Docker introduced multi-stage builds from version 17.05.
With multi-stage builds, you can split your Dockerfile into multiple sections. Each stage has its own FROM statement so you can involve more than one image in your builds. Stages are built sequentially and can reference their predecessors, so you can copy the output of one layer into the next.
With multi-stage build, we can use multiple base images in the Dockerfile and copy artifacts, configuration files, etc. From one stage to another, so that we can discard what we don’t need.
now let's create a Multi-stage dockerfile for our angular application. After this, the final size of our image will be in MBs.
Here’s a multi-stage Dockerfile which encapsulates our entire build:
Now we have a Dockerfile with two stages: first stage will be use to build image for angular application and generate a dist folder which contain all the deployable files for angular application.
Stage two will use another image to run an application.
so the size of our image is 110MB.
In this blog, We saw how to optimize our image from 1.28GB to 110MBs using different optimization methods.
In my next blog we'll learn how to start multiple containers at once using docker compose.
You can follow me, contact me, ask questions, see what I do, or use my open source code: