Cloud Native 19 min read

Unveiling Docker Image Internals: Layers, Storage, and Registry Mechanics

This article explains how Docker images are built on UnionFS with overlay2, describes the rootfs and layer design, details how containers mount image layers, outlines the directory layout of a Docker registry, and walks through the complete image upload, mounting, and security processes.

360 Zhihui Cloud Developer
360 Zhihui Cloud Developer
360 Zhihui Cloud Developer
Unveiling Docker Image Internals: Layers, Storage, and Registry Mechanics

Introduction

1. The nature of Docker images

Docker images are built on a UnionFS; the driver used is overlay2 (Docker) or overlayfs (containerd).

2. Rootfs and layer design

The base layer of an image is the rootfs, which packages the operating system, libraries and other dependencies so that containers run consistently across hosts.

Each instruction in a Dockerfile (RUN, ADD, etc.) creates a new layer. Multiple RUN commands can be combined into a single line to reduce the number of layers.

Only the topmost layer is writable; all lower layers are read‑only. Deletions in a read‑only layer are represented by whiteout files that hide the file in the upper layer.

Docker image layer diagram
Docker image layer diagram

3. Container image mounting

Docker supports several graph drivers (vfs, devicemapper, overlay, overlay2, aufs); the default storage driver is overlay2.

The default storage directory is /var/lib/docker .

<code>ls -lrt /var/lib/docker/</code>

Running a container creates a view layer under /var/lib/docker/overlay2 that contains diff , link , lower , merged , and work directories.

diff stores the data of each layer; link stores directory links to the underlying layers.

Layers are divided into three parts:

Read‑only layer

Init layer (holds files such as /etc/hosts , /etc/resolv.conf that need to be writable per container)

Read‑write layer (stores changes made inside the container)

All layers are mounted together under the merged directory, presenting a complete filesystem to the container.

<code>mount ... overlay ... lowerdir=... upperdir=... workdir=...</code>

2. Image storage structure in a registry and its usage

1. Directory layout of a local registry

Example path: /data/registry/docker/registry/v2

<code>├── blobs
│   └── sha256
│       └── ... (blob data and manifest JSON)
├── repositories
│   └── registry-share-private
│       ├── push-mount
│       │   ├── _layers
│       │   │   └── sha256
│       │   │       └── <layer‑sha> (link)
│       │   ├── _manifests
│       │   │   ├── revisions
│       │   │   │   └── sha256
│       │   │   │       └── <manifest‑sha> (link)
│       │   │   └── tags
│       │   │       └── v1
│       │   │           ├── current (link)
│       │   │           └── index (sha256)
│       │   └── _uploads
│       └── push-new
│           … (similar structure)
</code>

blobs store each layer’s gzip data and the image manifest (JSON). repositories store metadata such as repository name, tags, and links to layers.

2. Image upload process

Typical steps:

Authenticate and obtain a token.

Check whether a layer already exists with a HEAD request.

If the layer does not exist, start a blob upload ( POST ), optionally upload in chunks ( PATCH ), and finalize with PUT .

After all blobs are uploaded, push the manifest ( PUT /manifests/v1 ).

<code># Example authentication request
GET /v2/ HTTP/1.1
...
# Token request
GET /service/token?... HTTP/1.1
...
# Check layer existence
HEAD /v2/.../blobs/sha256:<layer> HTTP/1.1
...
# Start upload
POST /v2/.../blobs/uploads/ HTTP/1.1
...
# Upload chunk
PATCH /v2/.../blobs/uploads/<uuid>?_state=... HTTP/1.1
...
# Finalize upload
PUT /v2/.../blobs/uploads/<uuid>?digest=sha256:<layer> HTTP/1.1
...
# Push manifest
PUT /v2/.../manifests/v1 HTTP/1.1
{ "schemaVersion":2, "mediaType":"application/vnd.docker.distribution.manifest.v2+json", ... }
</code>

If a layer already exists in another repository and the client has read permission, Docker can mount the existing layer instead of uploading it again, which speeds up the push.

<code># Mount existing layer
POST /v2/.../blobs/uploads/?from=repo%2Fpush-new&mount=sha256:<layer> HTTP/1.1
</code>

If the layer exists but the client lacks permission, the layer must be re‑uploaded.

If the whole image already exists, a HEAD request on the manifest returns 200 , indicating that no upload is needed.

3. Image management and security

Image registry management – public (Docker Hub) vs private registries, role‑based access control, versioning.

Security scanning – use image scanning tools to detect vulnerabilities, sign and verify images to ensure provenance.

Resource utilization and cost control – minimize image size, reuse layers, and share storage to reduce storage and network costs.

Understanding Docker image internals, storage layout, and registry interactions helps build reliable, efficient, and secure container workflows.

DockersecurityoverlayfsImage RegistryContainer ImagesLayer Management
360 Zhihui Cloud Developer
Written by

360 Zhihui Cloud Developer

360 Zhihui Cloud is an enterprise open service platform that aims to "aggregate data value and empower an intelligent future," leveraging 360's extensive product and technology resources to deliver platform services to customers.

0 followers
Reader feedback

How this landed with the community

login 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.