Decreasing your Node.js Docker image size by 90%!

Pascal Zwikirsch
Jan 6 · 5 min read

I will show you in a few easy steps how to reduce the Docker image size of your Node.js app by around 90%.

Image for post
Image for post
Photo by Dominik Lückmann on Unsplash

Especially when working with public cloud and running your Docker images on their serverless environments it becomes more and more important that your Docker image size is as small as possible to reduce bootup time, cold start time, costs, and improve overall performance.

But oftentimes I see people still use the “full” image of their corresponding environment. So I want to show in this article how a one-liner in your Dockerfile can reduce the Docker image size of your application by around 90% without breaking your application.

In my example, I dockerized a small Node.js “Hello-World”-web server but since the actual application isn’t important in this article I won’t show its code here, but you can expect just a few KB of code here.

A typical Dockerfile for a Node.js environment might look like the following:

# Use Node.js v12
FROM
node:12

WORKDIR /usr/src/app

# Copy over the whole folder content
COPY
. ./

# Make a clean npm install and only install modules
# needed for production
RUN
npm ci --only=production

EXPOSE 8080

# Run the web service on container startup.
CMD
[ "npm", "run", "start" ]

With the npm ci --only=production command we already have a small optimization in place. Because we only install the modules defined in the dependencies section of our package.json so if you have a lot of modules in your devDependencies like eslint, jest, typescript, babeletc these won’t be installed so you already saved some space here. So make sure that you always have this line in your Dockerfile when you using NPM.

Running the above Dockerfile via docker build --tag docker-size-full:1.0 -f Dockerfile . results in a Docker image with a ridiculous size of 930MB!

Having already 930MB in size without any application code at all is of course a big performance killer, especially when you want to scale up with cloud container services like GCP Cloud Run.

So how can we now reduce these 930MB by around 90%? Here are two possibilities:

# Instead of using the full 930MB via 'FROM node:12'# Use the alpine image
FROM node:12-alpine
# OR
# Use the slim image
FROM node:12-slim

Pretty easy, right? You just have to change the very first statement in your Dockerfile.

The results of using the three different FROM statements can be seen in the below image:

Image for post
Image for post

As you can see the slim-variant is 83%! smaller than the full-variant and the alpine-variant is even 89%! smaller than the full one.

And I tell you something: Your Node.js script will run on all three of them! So there is absolutely no valid reason to use a super big Docker image if you can also use a smaller one.

So now you are for sure asking: “Why are there different images anyway? Can’t I simply always use the smallest one?”

And yeah, in my opinion, you should always use the smallest one, even if you don’t use the alpine one you should at least take the slim one, but never the full one for production applications. BUT you should know what is the difference, at least very roughly since you MIGHT run into some issues even though it's super unlikely and the alpine and slim variant will work for 99.9% of all software applications.

Alpine:

The alpine variant is based on Alpine Linux which is a very small image containing only the most important stuff. It also contains some “unusual” libs which might cause an issue when e.g. using Python, even so very unlikely, but with Node.js you shouldn’t run into any issues.

Slim:

This image does not contain the common packages contained in the full image and only contains the minimal packages needed to run node.

Summary
You should have seen now how easy it is to reduce your Docker image size by around 90% when you were still using the full version of Node.js.

If you don’t run into any unusual runtime issues it makes always sense to use the smallest image possible for your application to speed up your application and reduce costs when being billed my time consumed e.g. in the cloud environments. So you should always try to go with the alpine image first. If you really stumble into unusual errors you can always go “up” to using the slim variant, but if you don’t run into issues there is no reason to make your image bigger than needed.

Thanks for taking the time to read my article.

If you have any questions or additions feel free to use the comment section or hit me up on LinkedIn or Twitter to get in contact with me 😊

Image for post
Image for post

👋 Join FAUN today and receive similar stories each week in your inbox! Get your weekly dose of the must-read tech stories, news, and tutorials.

Follow us on Twitter 🐦 and Facebook 👥 and Instagram 📷 and join our Facebook and Linkedin Groups 💬

Image for post
Image for post

FAUN

The Must-Read Publication for Creative Developers & DevOps Enthusiasts

By FAUN

Medium’s largest and most followed independent DevOps publication. Join thousands of aspiring developers and DevOps enthusiasts Take a look.

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Pascal Zwikirsch

Written by

Development Team Lead | Passionate Developer

FAUN

FAUN

The Must-Read Publication for Creative Developers & DevOps Enthusiasts. Medium’s largest DevOps publication.

Pascal Zwikirsch

Written by

Development Team Lead | Passionate Developer

FAUN

FAUN

The Must-Read Publication for Creative Developers & DevOps Enthusiasts. Medium’s largest DevOps publication.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store