How to Reduce Docker Image Size: Optimization Methods
Software development often involves multiple versions/releases of a service, each with additional dependencies, commands, and configurations. This complexity poses a challenge for Docker image builds, requiring more time and resources.
Instances have been observed where initial application images grew from 350MB to over 1.5 GB due to accumulating dependencies and configurations.
Installing unnecessary libraries can increase the potential security risks by expanding the attack surface.
DevOps engineers should prioritise Docker image optimisation to prevent bloating after application builds or future releases, not only in production but at every stage in the CI/CD process.
Small-sized images are advantageous, especially in container orchestration tools like Kubernetes, as they reduce image transfer and deployment time.
How to Reduce Docker Image Size?
If we take a container image of a typical application, it contains a base image, Dependencies/Files/Configs, and cruft (unwanted software).
The following are the methods by which we can achieve docker image optimization.
- Using distroless/minimal base images
- Multistage builds
- Minimizing the number of layers
- Understanding caching
- Using Dockerignore
- Keeping application data elsewhere
Reducing Docker Image Size from 1.13 GB to Minimal 200 MB Range Dockerfile:
# Use the official Node.js image as the base image
FROM node
# Set the working directory inside the container
WORKDIR /app
# Copy package.json and package-lock.json to the container
COPY package*.json ./
# Install dependencies
RUN npm install
# Copy all application files to the container
COPY . .
# Expose the port your Node.js app listens on (3000 in this case)
EXPOSE 3000
# Start the Node.js application
CMD ["node", "app.js"]
Result:
$ docker images | grep gudditi/node-app
gudditi/node-app normal_image 9abe4f73d20e 30 seconds ago 1.13GB
Method 1: Use Minimal Base Images
# Use the official Node.js image as the base image
FROM node:slim
# Set the working directory inside the container
WORKDIR /app
# Copy package.json and package-lock.json to the container
COPY package*.json ./
# Install dependencies
RUN npm install
# Copy all application files to the container
COPY . .
# Expose the port your Node.js app listens on (3000 in this case)
EXPOSE 3000
# Start the Node.js application
CMD ["node", "app.js"]
Result:
$ docker images | grep gudditi/node-app
gudditi/node-app normal_image 9abe4f73d20e 30 seconds ago 1.13GB
gudditi/node-app latest f7c43c254bb1 20 minutes ago 282MB
Method 2: Use Docker Multistage Builds
# Use a builder stage with the full Node.js image for building the applicationFROM node:slim as builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
# Use a slim Node.js image as the final base imageFROM node:slim
WORKDIR /app
# Copy only the necessary files from the builder stageCOPY --from=builder /app ./
EXPOSE 3000
CMD ["node", "app.js"]
Result:
$ docker images | grep gudditi/node-app
gudditi/node-app minimal_image 518dcc04fb80 14 seconds ago 261MB
gudditi/node-app normal_image 9abe4f73d20e 22 minutes ago 1.13GB
gudditi/node-app latest f7c43c254bb1 42 minutes ago 282MB
Comments
Post a Comment