Cloud Native 11 min read

Master Docker Image Layers: Build, Optimize, and Understand Storage

This article walks through building a Docker image, explains the Union File System underlying Docker's layered storage, analyzes image and container file system structures, and presents practical Dockerfile optimization techniques to reduce image size and improve build efficiency.

NetEase Smart Enterprise Tech+
NetEase Smart Enterprise Tech+
NetEase Smart Enterprise Tech+
Master Docker Image Layers: Build, Optimize, and Understand Storage

Introduction

We will build a Docker image, instantiate a container, and analyze Docker's file storage and Dockerfile optimization strategies throughout the image lifecycle.

Union File System

The Union File System (UFS) is the technical foundation of Docker images, allowing file system modifications to be recorded as layered commits and enabling different directories to be mounted into a single virtual file system. Image layering and inheritance rely on this feature.

Docker Image Example

Below is a simplified Dockerfile used to create a JDK8 base image on a Debian 9.1 system (Docker 17.06.2‑ce, default overlay2 driver):

FROM hub.c.163.com/library/debian:stretch
MAINTAINER nim
# Download JDK
ADD http://10.173.11.100/nim/jdk-8u202-linux-x64.tar.gz /usr/local/nim/
# Extract JDK and remove archive
RUN tar -xzvf /usr/local/nim/jdk-8u202-linux-x64.tar.gz -C /usr/local/nim/ \
    && rm /usr/local/nim/jdk-8u202-linux-x64.tar.gz
# Set environment variables
ENV JAVA_HOME=/usr/local/nim/jdk1.8.0_202
ENV PATH=$JAVA_HOME/bin:$PATH
CMD ["/bin/bash"]

The resulting image grows from the original 100 MB base to 697 MB after adding JDK.

Image Layer Storage

Using docker history we see three layers: the base (100 MB), an ADD layer (≈194 MB), and a RUN layer (≈403 MB). The overlay2 storage directory /var/lib/docker/overlay2/ contains four sub‑directories: the base layer (≈110 MB), the ADD JDK layer (≈186 MB), and the JDK extraction layer (≈389 MB). Soft links in the l directory provide short names for each layer.

Layer Content Details

Each layer has a diff directory holding its file changes and a link file with the short name. The JDK ADD layer contains the compressed archive, while the extraction layer stores the uncompressed files; the archive is removed to save space.

Optimized Dockerfile

To avoid the JDK archive persisting in the image, we combine download, extraction, and cleanup in a single RUN statement and use curl instead of ADD:

FROM hub.c.163.com/library/debian:stretch
MAINTAINER nim
RUN curl -o /usr/local/nim/jdk-8u202-linux-x64.tar.gz http://10.173.11.100/nim/jdk-8u202-linux-x64.tar.gz \
    && tar -xzvf /usr/local/nim/jdk-8u202-linux-x64.tar.gz -C /usr/local/nim/ \
    && rm /usr/local/nim/jdk-8u202-linux-x64.tar.gz \
    && export JAVA_HOME=/usr/local/nim/jdk1.8.0_202 \
    && export PATH=$JAVA_HOME/bin:$PATH
CMD ["/bin/bash"]

This reduces the number of layers and eliminates the leftover JDK archive, shrinking the final image size.

General Optimization Tips

Combine related RUN statements to reduce layer count.

Leverage Docker build cache by placing stable commands early.

Clean up intermediate artifacts within the same layer they are created.

Prefer ADD alternatives (e.g., curl + tar) when you can handle extraction yourself.

Use fast, reliable base image mirrors to speed up downloads.

Image Metadata

Docker stores metadata in three main directories:

/var/lib/docker/image/overlay2/imaged/
/var/lib/docker/image/overlay2/layerdb/
/var/lib/docker/overlay2/

The first holds image JSON metadata, the second contains per‑layer metadata (cache‑id, diff, size), and the third stores the actual layered filesystem data.

Container Layer

When a container is created, Docker generates an initial read‑only layer and a writable layer under /var/lib/docker/overlay2/. The writable layer records changes made by the container; the merged view presents a unified filesystem to processes inside the container.

Multiple containers based on the same image share the read‑only layers, consuming only additional space for their individual writable layers (copy‑on‑write).

Conclusion

Understanding Docker image and container file systems is essential for efficient image management and operation in private‑cloud environments. Proper layering, cleanup, and build‑time optimizations lead to smaller images, faster builds, and more maintainable Dockerfiles.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

optimizationContainerImageFilesystemUnion File Systemoverlay2
NetEase Smart Enterprise Tech+
Written by

NetEase Smart Enterprise Tech+

Get cutting-edge insights from NetEase's CTO, access the most valuable tech knowledge, and learn NetEase's latest best practices. NetEase Smart Enterprise Tech+ helps you grow from a thinker into a tech expert.

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.