Optimizing the docker image size for your react application

Generated by DALL·E

if you have been working on a web development project for a long time, you already know how containerization is useful. Although there are some alternative ways to deploy your apps without containerizing them (like Vercel and Netlify). But if your company is using containers to deploy frontend applications on cloud services and you are looking to optimize the image then this blog is for you!

Why do we need to optimize the docker image size?

  1. Faster Build and Deployment Times: Smaller images require less time to build and deploy. This is particularly important in continuous integration and deployment (CI/CD) pipelines, where frequent updates are common. Faster builds and deployments mean quicker turnaround times for new features and bug fixes.

  2. Reduced Storage and Bandwidth Requirements: Smaller images consume less storage space in registries and on servers. This is cost-effective, especially when using cloud services where storage costs money.

  3. Efficient Resource Utilization: In environments where resources are shared (like Kubernetes clusters), using smaller images can lead to more efficient utilization of underlying hardware. This efficiency can translate into cost savings, especially in cloud environments where resource usage directly impacts billing.

Steps for creating and optimizing docker image size

Note: I will start by creating a react app and containerizing it. if you already know these steps you can skip these steps.

Step 1 - Create a react project

You can create a project using CRA or Vite. I have used Vite

npm create vite@latest

it will ask you some questions

Step 2 - Create a docker file

here is a basic dockerfile for the react application

# Fetching the latest node image on bullseye linux
FROM node:20-bullseye as build

# Declaring env
ENV NODE_ENV development

# Setting up the work directory
WORKDIR /react-app

# Installing dependencies
COPY ./package.json /react-app
RUN npm install

# Copying all the files in our project
COPY . .

# Starting our application
CMD npm start

To build the image from the docker file. (You will need to keep docker desktop running)

docker build -t my-react-app .

Now you can see the created image in the docker desktop

And it's pretty big!

Step 3 - Optimize the size

In our dockerfile we need to tweak one line of code and now create a image again. Change our node image distribution.(Which is first line in dockerfile)

# Fetching the latest node image on Alpine Linux (THIS IS THE CHANGE, USED ALPINE)
FROM node:20-alpine as build  

# Declaring env
ENV NODE_ENV development

# Setting up the work directory
WORKDIR /react-app

# Installing dependencies
COPY ./package.json /react-app
RUN npm install

# Copying all the files in our project
COPY . .

# Starting our application
CMD npm start

and our image size has decreased by 63.91%.

Why did one line make so much change?

There are different Linux distributions for node images. Using the Alpine Linux distribution in Docker images, such as node:alpine for Node.js, can significantly reduce the Docker image size. The reasons for this are rooted in the design and architecture of Alpine Linux:

  1. Minimalist Design: Alpine Linux is designed to be small, simple, and secure. It uses musl libc and busybox, which are much smaller than the glibc and the usual Linux utilities found in other distributions. This minimalist design approach results in a significantly smaller base image size.

  2. Smaller Footprint: Alpine's small footprint means that when it's used as a base image, the overall size of the Docker image is reduced. This is especially beneficial for applications that don't require the full capabilities of larger distributions like Ubuntu or Debian.

  3. Fewer Pre-Installed Packages: Alpine comes with fewer pre-installed packages. In larger distributions, there are often many packages installed by default, which may not be necessary for your application, thus contributing to a larger image size. With Alpine, you add only what you need, keeping the image lean.

Conclusion

In conclusion, optimizing your Docker image size for a React application is crucial for enhancing efficiency and performance. By employing strategies like using Alpine Linux, leveraging multi-stage builds, and carefully managing included files, you can significantly reduce your image size. This leads to faster deployment times, reduced costs, and a more streamlined development process. Embrace these practices to make your React applications not just powerful, but also remarkably efficient in a containerized environment. Happy coding!

You can connect with me on LinkedIn and Twitter

Hit that follow button for more development-related content!