Building Reeeaaally Small Docker Images
From 768 MB to 117 MB.
1. Build A Basic Dockerfile
Let’s create a basic GraphQL Server with graphql-yoga.
If you know your Docker-fu, this isn’t really the best Dockerfile in the world. The Node base image is bigger than we need it to be, we have a bunch of layers, etc.
johnpaulada/really-small-graphql-server-image latest 768MB
768 MB huh. That’s pretty big. Let’s make it a bit smaller.
2. Using Multi-stage Builds
Multi-stage builds allow us to install the dependencies and build executables but only copy the files we need for our final image, reducing its size. We enable multi-stage builds by adding another FROM command. The last FROM command will be the final image.
If you didn’t know, almost each line in a Dockerfile amounts to one layer in a container. That means each line in a Dockerfile contributes to its size. Here, we install graphql-yoga in one of these lines. By using multi-stage builds, we can add a lot of those layers but we’ll only copy what we need to the final image, therefore, those previous layers are no longer part of the final image. This makes the image smaller.
johnpaulada/really-small-graphql-server-image latest 718MB
Okay we managed to remove 50 MB from there. But that’s still far from small. What else can we do?
3. Use Distroless Images
That huge size of 718 MB was mostly because of the Node base image. To remedy this, we can use smaller base images, like Google Cloud Platform’s Distroless images, which they describe as:
Language focused docker images, minus the operating system.
That sounds exactly what we need right now?
Let’s pull up the Node distroless image and use it as the new base of our final build phase.
johnpaulada/really-small-graphql-server-image latest 117MB
Just by using a distroless image, we shaved 601 MB off our final image!
Using a combination of Multi-stage builds and Distroless images, we can make our Docker images exponentially smaller.
If you liked this article, hold the 👏 button and follow us! Thank you!