CodeGym /Courses /Docker SELF /Dockerfile Optimization

Dockerfile Optimization

Docker SELF
Level 14 , Lesson 0
Available

6.1 Getting to Know Image Optimization

Docker images, while compact, still take up space. So, reducing their size is super important—it helps boost performance, speeds up loading and deploying containers, and cuts down on storage costs. You can optimize an image by improving the Dockerfile since it can be organized in different ways. In this lecture, we'll go over a few strategies and best practices to create optimized and lightweight Docker images.

Why is it important to reduce Docker image size?

  1. Deployment speed: Smaller images load faster from the Docker registry and deploy into containers more quickly, which is especially crucial in automated CI/CD systems.
  2. Efficient resource usage: Lightweight images take up less disk space, save network resources during transfer, and ensure more efficient use of computing power.
  3. Security: Smaller images typically include fewer unnecessary components, reducing the risk of potential vulnerabilities.
  4. Simplifying updates: Updating lightweight images is faster and uses fewer resources, accelerating the support process.

6.2 Strategies for Reducing Docker Image Size

1. Using Minimal Base Images

Choosing a base image directly affects the final Docker image size. Using minimal base images like alpine can significantly shrink the image size.

Example:

Replacing the ubuntu image with alpine:

dockerfile

# FROM ubuntu:20.04
FROM alpine:3.12

alpine is a lightweight Linux distribution that takes up about 5 MB, while the ubuntu image can take up hundreds of megabytes.

2. Minimizing the Number of Layers

Each instruction in the Dockerfile adds a new layer to the image. Combining multiple commands into one RUN instruction reduces the number of layers, which helps shrink the total image size.

Example:

Before optimization:

dockerfile

RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y git
RUN rm -rf /var/lib/apt/lists/*

After optimization:

dockerfile

RUN apt-get update && apt-get install -y curl git && rm -rf /var/lib/apt/lists/*

Deleting the package manager cache (rm -rf /var/lib/apt/lists/*) further reduces the image size by removing temporary files created during the installation.

3. Removing Temporary Files

Deleting temporary files and unnecessary data after installing packages keeps the image clean and lightweight.

Example:

dockerfile


RUN apt-get update && apt-get install -y curl git && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

4. Using .dockerignore

The .dockerignore file helps exclude unnecessary files and directories from the build context, reducing the image size and speeding up the build process.

Example .dockerignore:

Terminal


node_modules
dist
*.log
Dockerfile*
.dockerignore

5. Multi-Stage Builds

Multi-stage builds allow you to use multiple intermediate images to create a final lightweight image containing only the necessary files and dependencies.

Example:

dockerfile


# Build stage
FROM node:14 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# Final stage
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html

In this example, the first stage builds the application, and the final stage uses only the build results, reducing the size of the final image.

6. Optimizing Package Installation

Installing only necessary packages and using package manager options for minimal installation help reduce the image size.

Example:

Using the --no-install-recommends option with apt-get:

dockerfile


RUN apt-get update && apt-get install -y --no-install-recommends curl git && \
    rm -rf /var/lib/apt/lists/*

7. Compressing and Minimizing Data

Using tools for compressing and minimizing data helps shrink the image size.

Example:

Compressing text files and log files:

dockerfile


RUN gzip /path/to/large/file.log

8. Removing Unused Libraries and Dependencies

Removing unused libraries and dependencies after installing the necessary packages keeps the image lightweight.

Example:

For Python applications:

dockerfile


RUN pip install --no-cache-dir -r requirements.txt

6.3 Examples of Optimized Dockerfile

Example 1: Optimized Dockerfile for Node.js

dockerfile

FROM node:14-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
        
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html

This example uses a multi-stage build. First, the app is built in an intermediate stage, and then only the build results are copied to the final image based on Nginx.

Example 2: Optimized Dockerfile for Python

dockerfile

FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "app.py"]

This example uses a lightweight base image python:3.9-slim. Installing dependencies is placed in a separate step, which allows Docker to use caching if the requirements.txt file hasn’t changed.

3
Task
Docker SELF, level 14, lesson 0
Locked
Using a minimal base image
Using a minimal base image
3
Task
Docker SELF, level 14, lesson 0
Locked
Combining commands to reduce layers
Combining commands to reduce layers
3
Task
Docker SELF, level 14, lesson 0
Locked
Using .dockerignore to reduce the build context
Using .dockerignore to reduce the build context
3
Task
Docker SELF, level 14, lesson 0
Locked
Multistage build to reduce the final image size
Multistage build to reduce the final image size
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION