How to Shrink Docker Images: From 1.16 GB to 22 MB with Multi‑Stage Builds
This article explains Docker fundamentals and demonstrates step‑by‑step image optimizations—using Alpine base images, multi‑stage builds, and Nginx—to reduce a React app container from over a gigabyte down to just 22 MB while preserving functionality.
Docker Overview
Docker is a platform that lets developers and system administrators build, run, and share applications inside containers. A container runs as an isolated process with its own filesystem created from a Docker image, which bundles compiled code, dependencies, libraries, and is defined by a Dockerfile. The terms “dockerization” or “containerization” refer to the process of creating Docker containers.
Why Containers Are Popular
Flexibility – even the most complex applications can be containerized.
Lightweight – containers share the host kernel, making them far more efficient than virtual machines.
Portability – build locally and run anywhere.
Loose coupling – containers are self‑contained; replacing or upgrading one does not interrupt others.
Security – containers enforce strict process isolation without additional configuration.
This article concentrates on techniques for optimizing Docker images to make them lightweight.
Optimization Process
We start with a sample React application that is containerized. After running npx create-react-app app --template typescript we obtain the file structure shown below.
npx create-react-app app --template typescriptA basic Dockerfile produces a 1.16 GB image:
FROM node:10
WORKDIR /app
COPY app /app
RUN npm install -g webserver.local
RUN npm install && npm run build
EXPOSE 3000
CMD webserver.local -d ./buildStep 1 – Use a Lightweight Base Image
Alpine‑based images are much smaller than Ubuntu‑based ones because they contain only the essential packages. Replacing the base image with node:10‑alpine reduces the image size to about 330 MB.
FROM node:10-alpine
WORKDIR /app
COPY app /app
RUN npm install -g webserver.local
RUN npm install && npm run build
EXPOSE 3000
CMD webserver.local -d ./buildStep 2 – Multi‑Stage Build
Multi‑stage builds allow us to compile the application in one stage and copy only the final artifacts into a second, minimal stage. This removes source files, node_modules, and package.json, shrinking the image to 91.5 MB.
FROM node:10-alpine AS build
WORKDIR /app
COPY app /app
RUN npm install && npm run build
FROM node:10-alpine
WORKDIR /app
RUN npm install -g webserver.local
COPY --from=build /app/build ./build
EXPOSE 3000
CMD webserver.local -d ./buildStep 3 – Serve with Nginx
Node is not optimal for serving static web assets. Replacing the runtime with Nginx further reduces the image to 22.4 MB and serves the built React files correctly.
FROM node:10-alpine AS build
WORKDIR /app
COPY app /app
RUN npm install && npm run build
FROM nginx:stable-alpine
COPY --from=build /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Open Source Linux
Focused on sharing Linux/Unix content, covering fundamentals, system development, network programming, automation/operations, cloud computing, and related professional knowledge.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
