How to Shrink Docker Images from 1.16 GB to 22 MB: Step‑by‑Step Optimization
This article explains Docker fundamentals, outlines why containers are popular, and walks through a practical example of reducing a React app's Docker image size from 1.16 GB to 22 MB using a lightweight Alpine base, multi‑stage builds, and an Nginx final stage.
Docker Introduction
Docker is a platform that lets developers and system administrators build, run, and share applications using containers. A container runs as an isolated process with its own filesystem built from a Docker image that contains everything needed to run the application, defined by a Dockerfile.
The terms dockerization or containerization refer to the process of creating Docker containers.
Containers are popular because they offer several advantages:
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, run anywhere.
Loose coupling – a container is self‑contained; replacing or upgrading one container does not disrupt others.
Security – containers enforce strict isolation without additional configuration.
This article focuses on optimizing Docker images to make them lightweight.
Optimization Process
We start with a sample React application. After running npx create-react-app app --template typescript and creating a Dockerfile, the initial image size is 1.16 GB.
FROM node:10<br/>WORKDIR /app<br/>COPY app /app<br/>RUN npm install -g webserver.local<br/>RUN npm install && npm run build<br/>EXPOSE 3000<br/>CMD webserver.local -d ./buildStep 1: Use a Lightweight Base Image
Switching the base image from the default to an Alpine‑based image reduces the size dramatically. Alpine images contain only the minimal required packages.
FROM node:10-alpine<br/>WORKDIR /app<br/>COPY app /app<br/>RUN npm install -g webserver.local<br/>RUN npm install && npm run build<br/>EXPOSE 3000<br/>CMD webserver.local -d ./buildResulting image size: ~330 MB.
Step 2: Multi‑Stage Build
Multi‑stage builds allow us to compile the application in one stage and copy only the compiled output to a final, minimal image, discarding source files, node_modules, and package.json.
FROM node:10-alpine AS build<br/>WORKDIR /app<br/>COPY app /app<br/>RUN npm install && npm run build<br/>FROM node:10-alpine<br/>WORKDIR /app<br/>RUN npm install -g webserver.local<br/>COPY --from=build /app/build ./build<br/>EXPOSE 3000<br/>CMD webserver.local -d ./buildResulting image size: ~91.5 MB.
Step 3: Use Nginx for Static Content
Serving static files with Nginx is more efficient than using a Node container. The final Dockerfile builds the React app in the first stage and copies the built assets into an nginx:stable-alpine image.
FROM node:10-alpine AS build<br/>WORKDIR /app<br/>COPY app /app<br/>RUN npm install && npm run build<br/>FROM nginx:stable-alpine<br/>COPY --from=build /app/build /usr/share/nginx/html<br/>EXPOSE 80<br/>CMD ["nginx", "-g", "daemon off;"]Resulting image size: ~22.4 MB, and the container serves the React application correctly.
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.
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
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.
