Cloud Native 15 min read

How to Shrink Docker Images by Up to 98%: Practical Labs and Tips

This step‑by‑step guide explains Docker image layers, demonstrates seven labs that progressively reduce image size using smaller base images, RUN command chaining, export/import compression, scratch builds, dynamic library extraction, and static Go binaries, achieving reductions from hundreds of megabytes to just a few megabytes.

Go Development Architecture Practice
Go Development Architecture Practice
Go Development Architecture Practice
How to Shrink Docker Images by Up to 98%: Practical Labs and Tips

Introduction

Docker images can become surprisingly large; a hub.c.163.com/public/logo image that fits on a T‑shirt is only 585 bytes, while many real‑world images exceed hundreds of megabytes. Reducing image size saves storage, bandwidth, and speeds deployment.

Image Layers

Each instruction in a Dockerfile creates a new layer. Layers rely on copy‑on‑write filesystems and union mounts, so every layer adds to the final image size even if the command does nothing useful.

Lab 1 – Build a Redis Image from Ubuntu

FROM ubuntu:trusty
ENV VER 3.0.0
ENV TARBALL http://download.redis.io/releases/redis-$VER.tar.gz
# install build tools
RUN apt-get update && apt-get install -y curl make gcc
# download and compile
RUN curl -L $TARBALL | tar zxv && cd redis-$VER && make && make install
# clean up
RUN apt-get remove -y --auto-remove curl make gcc && apt-get clean && rm -rf /var/lib/apt/lists/* redis-$VER
CMD ["redis-server"]

Build command: docker build -t redis:lab-1 . The resulting image is 106 MB, far larger than the 1 MB base because each RUN added a layer.

Lab 2 – Use a Smaller Base Image

Replace ubuntu:trusty with debian:jessie, which is only ~85 MB. After rebuilding, the image size drops from 347 MB to 305 MB, a modest 42 MB reduction.

Lab 3 – Chain RUN Instructions

Combine multiple commands into a single RUN using &&. Example:

FROM debian:jessie
ENV VER 3.0.0
ENV TARBALL http://download.redis.io/releases/redis-$VER.tar.gz
RUN echo "Install tools" && apt-get update && apt-get install -y curl make gcc \
    && echo "Download & compile" && curl -L $TARBALL | tar zxv && cd redis-$VER && make && make install \
    && echo "Clean up" && apt-get remove -y --auto-remove curl make gcc && apt-get clean && rm -rf /var/lib/apt/lists/* redis-$VER
CMD ["redis-server"]

Rebuilding yields a 151 MB image – roughly a 50 % reduction compared with the original Ubuntu‑based build.

Lab 4 – Export / Import Compression

Docker’s export and import commands can flatten an image:

docker run -d redis:lab-3
docker export 71b1c0ad0a2b | docker import - redis:lab-4

This method discards metadata such as exposed ports and default commands, so it is useful only for experimental size testing.

Lab 5 – Build from scratch or busybox

The scratch image is empty; you add only the files you need. By extracting the dynamic libraries required by redis‑server with ldd and packing them into rootfs.tar.gz, a final image based on scratch is only 7.73 MB.

FROM scratch
ADD rootfs.tar.gz /
COPY redis.conf /etc/redis/redis.conf
EXPOSE 6379
CMD ["redis-server"]

Lab 6 – Extract Dynamic Libraries

Example workflow:

# List shared libraries
ldd redis-3.0.0/src/redis-server
# Package them
tar czvf rootfs.tar.gz lib/x86_64-linux-gnu/*.so* redis-3.0.0/src/redis-server
# Build with the Dockerfile shown in Lab 5

Lab 7 – Minimal Go Image

Go produces static binaries that can be copied into scratch directly:

FROM scratch
COPY hello /hello
ENTRYPOINT ["/hello"]

Using the centurylink/golang-builder container to compile the program results in a 1.59 MB image.

Summary

The experiments demonstrate three practical techniques for shrinking Docker images: (1) start from the smallest possible base image (e.g., debian:jessie, busybox, or scratch); (2) chain multiple RUN commands to avoid creating unnecessary layers; and (3) rebuild or export the image to remove intermediate metadata. Applying these methods can reduce a 300 MB image to 150 MB or less, and in extreme cases (static Go binaries or scratch) to under 10 MB.

Layer diagram
Layer diagram
Docker layer illustration
Docker layer illustration
Redis build example
Redis build example
Scratch image example
Scratch image example
Dockerimage-optimizationdevopscontainer
Go Development Architecture Practice
Written by

Go Development Architecture Practice

Daily sharing of Golang-related technical articles, practical resources, language news, tutorials, real-world projects, and more. Looking forward to growing together. Let's go!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.