Hack Your Docker Builds: Optimize, Accelerate, Dominate

Stop shipping inflated Docker images! Optimize for speed, security & size build lean, deploy fast!

Docker revolutionizes application deployment, but with images that aren't optimized correctly, you might get slow builds, storage-consuming images, and wasteful deployments. Optimized Docker images are faster to build, smaller in size, and overall more performant. We will discuss realistic strategies to get your Docker images leaner and faster in this guide.


Why Optimize Docker Images?

  • Well-structured Dockerfiles cuts the build time, speeding up CI/CD pipelines.

  • Lightweight images consume less bandwidth and save storage costs.

  • Minimizing unnecessary components reduces the attack surface of your application.


Some of the elements that we can tune to obtain our Ideal Builds.


1. Choose a Minimal Base Image

The base image significantly impacts the final image size. Using lightweight base images can drastically reduce image size.

Best Minimal Base Images:

  • alpine (~5 MB) – Lightweight, fast, and secure.

  • distroless – Only includes runtime dependencies, reducing security risks.

  • scratch – An empty base image, best for statically compiled binaries.

Example: Switching from Ubuntu to Alpine

# Bad (Large Size)
FROM ubuntu:latest

# Good (Lightweight)
FROM alpine:latest

2. Optimize Layering & Leverage Build Caching

Docker builds images layer by layer, caching steps to avoid unnecessary rebuilds. Poor layering can break caching and slow down builds.

Best Practices:

  • Place frequently changing instructions (e.g., COPY .) at the bottom of the Dockerfile.

  • Install dependencies before copying application code to improve caching.

  • Reduce the number of layers by combining commands.

Example: Optimized caching for a Node.js app

# Bad (Breaks Caching)
FROM node:18
COPY . /app
RUN npm install

# Good (Optimized Caching)
FROM node:18
WORKDIR /app
COPY package.json package-lock.json /app/
RUN npm install
COPY . /app/

Here, Docker caches the npm install step if the package.json remains unchanged, speeding up rebuilds.


3. Remove Unnecessary Dependencies

Unused packages increase image size and security risks. Clean up temporary files and avoid installing unnecessary dependencies.

Example: Cleaning up after package installation

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

4. Use Multi-Stage Builds to Reduce Image Size

Multi-stage builds help by building artifacts in one stage and copying only necessary files into the final image, reducing size and dependencies.

Example: Multi-stage build for a Go application

# First stage (Build)
FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN go build -o app

# Second stage (Runtime)
FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/app .
CMD ["./app"]

The final image is much smaller since it doesn’t include compilers or build tools.


5. Use .dockerignore to Exclude Unnecessary Files

Prevent unnecessary files from being copied into the image by using a .dockerignore file.

Example: .dockerignore file

node_modules
.git
*.log
.env

6. Compress & Optimize Image Layers

  • Use Docker image squashing: --squash flag in docker build.

  • Remove unused images & containers:

    docker system prune -a

7. Use Slim Variants of Base Images

Many official images provide slim variants that remove unnecessary tools and files.

Recommended Slim Variants:

  • python:3.11-slim instead of python:3.11

  • debian:bullseye-slim instead of debian:bullseye


8. Avoid ADD in Favor of COPY

ADD has hidden behaviors like auto-extracting archives and supporting URLs, which can introduce unintended files and security risks

Use COPY instead of ADD

COPY file.tar.gz /app/


Instead of:

ADD file.tar.gz /app/

If extraction is needed, use RUN tar -xzf file.tar.gz.


8. Use LABEL to Add Metadata Efficiently

Adding metadata like versioning, authors (maintainers), and descriptions help in image management and debugging.

LABEL maintainer="Aditya Dhopade <[email protected]>"
LABEL version="1.0.0"
LABEL description="Optimized lightweight Node.js app"

9. Parallelize Package Installations

Package managers often support parallel downloads, which can drastically cut build times.

Parallel Package Installations for apt-get

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

10. Use Shells Depending on Images

Many images come with Bash, but if your app doesn’t need it, you can use sh or ash instead.


Switch to ash for Alpine-based images

RUN apk add --no-cache busybox-extras
SHELL ["/bin/ash", "-eo", "pipefail", "-c"]


Can use dash instead of bash in Debian-based images

RUN apt-get install -y dash
SHELL ["/bin/dash", "-eo", "pipefail", "-c"]


11. [BONUS] Use lazy-pull for Faster Deployments


From Docker 24.0 onwards they have introduced lazy-pulling where only the needed parts of an image are pulled instead of downloading the full image upfront

To enable it can be done using

docker run --pull=always --lazy-pull my-image

This can significantly speed up deployments in cloud environments.

Congratulations you made it to the last !! Stay ahead; Subscribe to the EzyInfra Knowledge Base for more DevOps wisdom.


Conclusion

By following these best practices, you can create leaner, faster, and more secure Docker images:

  • Use minimal base images

  • Leverage caching effectively

  • Remove unnecessary dependencies

  • Adopt multi-stage builds

  • Utilize .dockerignore efficiently

Optimizing your Docker images isn’t just about speed—it’s about efficiency, security, and scalability.

Is Docker the only way to build Images ?

Nope, there are other ways to build. Wanna know more !?


EzyInfra.dev – Expert DevOps & Infrastructure consulting! We help you set up, optimize, and manage cloud (AWS, GCP) and Kubernetes infrastructure—efficiently and cost-effectively. Need a strategy? Get a free consultation now!

Share this post

Want to discuss about DevOps practices, Infrastructure Audits or Free consulting for your AWS Cloud?

Prasanna would be glad to jump into a call
Loading...