2024.12.14

7 Ultimate Hacks to Optimize Docker Image Size

docker

Guide to optimizing Docker image size: reduce size, improve CI/CD performance, and save storage resources efficiently.


 

1. Benefits of optimizing Docker image size

  • Reduced build and deploy time: Lightweight Docker images make the build and deploy processes faster, saving time in the CI/CD pipeline..
  • Storage savings: Optimized Docker images consume fewer storage resources, reducing storage costs on cloud or local systems.
  • Improved performance: Smaller images load faster, reducing latency when pulling/pushing images between environments.
  • Enhanced security: Minimal Docker images with fewer unnecessary dependencies reduce the potential attack surface.

2. Ways to optimize Docker image size

2.1. Use a lightweight base image

  • Method: Choose a small base image like Alpine instead of Ubuntu or Debian
  • Example:
# Dockerfile sử dụng base image Alpine
FROM node:18-alpine

WORKDIR /app

COPY package.json yarn.lock ./
RUN yarn install --production

COPY . .

CMD ["node", "index.js"]
  • Explain:
    • node:18-alpine: This is a Node.js version built on Alpine Linux, which is much smaller than node:18.
    • yarn install –production: Only install production dependencies, skipping devDependencies to reduce image size.

2.2. Use Multi-Stage Build

  • Method: Use multi-stage builds to remove unnecessary files and dependencies from the production image.
  • Example:
# Stage 1: Build application
FROM node:18 as builder

WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install
COPY . .
RUN yarn build

# Stage 2: Create production image
FROM nginx:alpine

COPY --from=builder /app/build /usr/share/nginx/html

EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
  • Explain:
    • FROM node:18 as builder: The first stage is used for building the code, and it can contain multiple build dependencies and tools.
    • COPY –from=builder: Only copy necessary artifacts from the build stage to the production image, omitting unnecessary files.

2.3. Removing unnecessary files from the image

  • Method: Using commands like rm to remove cache or unnecessary files after installing dependencies
  • Example:
FROM python:3.10-slim

WORKDIR /app

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

COPY . .

CMD ["python", "app.py"]
  • Explain:
    • –no-cache-dir: Avoid saving pip cache after installing dependencies
    • slim: Lightweight base image, reducing unnecessary tools.

2.4. Use .dockerignore

  • Method: Using a .dockerignore file to exclude unnecessary files from the build context is a common practice to optimize Docker image size.
  • Example:
# .dockerignore
node_modules
.env
dist
logs
  • Explain: Excluding directories like node_modules, logs, or temporary files that are not needed reduces the build context size and final image size.

2.5. Reducing the number of layers in a Dockerfile

  • Method: Combining multiple RUN instructions into a single line to reduce the number of layers created..
    • Example:
RUN apt-get update && apt-get install -y \
    curl \
    vim \
 && apt-get clean \
 && rm -rf /var/lib/apt/lists/*
    • Explain: Combining multiple RUN instructions into a single line to create a single layer, making the image more streamlined.

2.6. Use Docker BuildKit

  • Method: Docker BuildKit is an improved tool that enables faster and more efficient image builds. It supports better caching, parallel builds, and several features that help reduce image size.
  • Example:
# Enable BuildKit
# In terminal: export DOCKER_BUILDKIT=1

# Dockerfile
# Use cache mount to optimize apt-get and reduce dependencies
# Base image
FROM debian:bullseye-slim

# Install dependencies
RUN --mount=type=cache,target=/var/cache/apt \
    apt-get update && apt-get install -y curl && \
    apt-get clean && rm -rf /var/lib/apt/lists/*

WORKDIR /app
COPY . .

CMD ["bash"]
  • Explain:

    • –mount=type=cache: Using BuildKit to cache files from apt-get helps reduce the need to re-download files during multiple builds.
    • export DOCKER_BUILDKIT=1: Enable BuildKit when using Docker CLI.
    • Base image debian:bullseye-slim: A lightweight version of Debian, reducing the size of Docker images.

2.7. Reduce the number of dependencies

  • Method: Limit the number of dependencies by:

    • Installing only necessary libraries and tools.
    • Removing unused libraries from the application.
  • Example

FROM node:18-alpine

WORKDIR /app

# Copy chỉ các file cần thiết
COPY package.json yarn.lock ./

# Chỉ cài đặt dependencies cần thiết cho production
RUN yarn install --production

COPY . .

CMD ["node", "app.js"]
  • Explain:

    • –production: Install only production dependencies, skipping devDependencies to reduce the size.
    • COPY package.json yarn.lock ./ before: Helps to leverage cache when dependencies don’t change.

3. Summary

Optimizing Docker image size not only reduces costs and improves performance but also enhances application security. Investing time in learning and applying best practices will help you work more efficiently with Docker. Always check the image size using the docker images command and try to reduce it if necessary.

References

Related articles

Subscribe
Notify of
0 Comments
Inline Feedbacks
View all comments