avatarA K S

Summary

The article outlines the process of optimizing a Docker image for a Vite + React application using multi-stage builds to significantly reduce the image size.

Abstract

The author begins by addressing the common issue of bloated Docker images and describes their journey to slim down their Docker image for a Vite + React application. Initially, the Docker image was over 1.24 GB, which is considered large for a simple application. The article then delves into the solution: implementing multi-stage builds in the Dockerfile. This approach involves a build stage, where the application is compiled using a standard Node image, and a runtime stage, where only the essential build artifacts are copied into a lightweight Alpine-based Node image. By doing so, the author successfully reduces the image size to 191.4 MB, achieving faster deployment times, lower bandwidth usage, and overall more efficient resource management. The article concludes by emphasizing the benefits of this optimization process, advocating for the minimalist approach in Docker image creation.

Opinions

  • The author expresses dissatisfaction with the initial size of their Docker image, indicating it was unnecessarily large.
  • There is a clear endorsement of multi-stage builds as an effective method for reducing Docker image size.
  • The author believes that a smaller Docker image leads to several advantages, including quicker deployments and reduced bandwidth consumption.
  • The author is pleased with the results of the optimization, highlighting the satisfaction of a DevOps professional with the improved efficiency.
  • The article encourages readers to apply similar optimizations when Dockerizing their Vite + React applications, suggesting that sharing insights and knowledge can inspire and benefit others in the community.

Trimming the Docker Image: How I Made My Docker Images Slimmer with Vite, React, and Multi-Stage Builds

Docker Image with and without Multistage build

Ever felt your Docker images are wearing a few extra layers? I’ve been there. Dockerizing sample Vite + React app used to result in a chunky image. But then, I was introduced to multi-stage builds and everything changed. Let’s dive in, starting from the very beginning!

Step 1: Setting Up a React App with Vite

Before we even touch Docker, let’s get our React app up and running with Vite:

  • Create a New Project: Kickstart your React project with:
npm create vite@latest my-react-app -- --template vue --template react
Select React
Select Javascript
  • Navigate and Start:
cd my-react-app
npm install
npm run dev
React App running on localhost

Voilà! You should have a React app running smoothly with Vite.

Step 2: The Good Ol’ Dockerfile

Quick tip — before creating the Docker image:

If you want to run the app with Docker, you need to modify the vite.config.js present in your project.

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  server: {
    watch: {
      usePolling: true,
    },
    host: true, // needed for the Docker Container port mapping to work
    strictPort: true,
    port: 5173, // you can replace this port with any port
  }
});

Now, Here’s the Dockerfile I initially used for my Vite + React project:

FROM node
WORKDIR /app
COPY package.json .
RUN npm i
COPY . .
EXPOSE 5173
CMD ["npm", "run", "dev"]

Build the docker image:

docker build -t my-vite-react-app .

It’s straightforward, but the image size? A whopping 1.24 GB+.

Step 3: Slimming Down with Multi-Stage Builds

Multi-stage builds let us use multiple FROM statements in our Dockerfile. This means one stage for building and another for running, only carrying forward the essentials.

Here’s the revamped Dockerfile:

# ---- Build Stage ----
FROM node:latest AS build
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
RUN npm run build

# ---- Runtime Stage ----
FROM node:alpine
WORKDIR /app
# Install serve globally
RUN npm install -g serve
COPY --from=build /app/dist /app/dist

EXPOSE 5173
CMD ["serve", "-s", "dist", "-l", "5173"]

Build the docker image:

docker build -t my-vite-react-app-multistage .

See how the image size shrinks for the same app from 1.24 GB to 191.4 MB.

The magic:

  1. Build Stage: We use the standard Node image, get our dependencies, and build our app.
  2. Runtime Stage: We switch to the lightweight node:alpine, grab only the essentials, and install just the production dependencies.

Step 4: The Results

After this makeover, our Docker image went from chunky to sleek, shedding several hundred megabytes. Faster deployments, less bandwidth, and a happier DevOps (that’s me!).

Wrapping Up:

Starting with Vite for React and ending with a slim Docker image, we’ve journeyed through efficient app development and deployment. If you’re about to Dockerize your Vite + React app, remember: in the Docker world, less is often more!

P.S. If you found value in this article or it resonated with you, please consider giving it a clap 👏, share it around & comment. Your support not only encourages me to keep sharing insights but also helps others discover this content. Together, we can spread knowledge and inspire others. Thank you for being a part of this journey!”

Docker
React
Vitejs
DevOps
Web Development
Recommended from ReadMedium