Where Are Docker Images Stored? File Locations Explained

Summarize this article with:

Docker images take up more disk space than most developers expect. Understanding where Docker images are stored on your system, whether locally on Linux, macOS, or Windows, or remotely in a container registry, is the first step to managing that storage properly.

This article covers the exact default storage paths for each operating system, how the overlay2 storage driver manages image layers on disk, and where remote registries like Docker Hub keep your pushed images.

You will also learn how to change the default storage location, clean up unused images, and handle image storage in Kubernetes environments running containerd or CRI-O.

What Are Docker Images

maxresdefault Where Are Docker Images Stored? File Locations Explained

A Docker image is a read-only template that packages everything an application needs to run. Code, runtime, system libraries, dependencies, and configuration files all get bundled into one portable unit.

Think of it as a snapshot of a filesystem. Not a full operating system, just the parts your application actually needs.

Images are built in layers. Each instruction in a Dockerfile (a COPY, a RUN, an apt-get install) creates a new layer on top of the previous one. These layers stack using a union filesystem, so the final image is a composite of every change made during the build process.

This layered approach is a big deal for storage. Layers get shared between images. If ten images all start from the same Ubuntu base, that base layer only exists once on disk. Docker uses content-addressable storage with SHA256 digests to track and deduplicate these layers. A study analyzing the Docker Hub dataset found that 50% of image layers are smaller than 4 MB, and only about 3% of files across layers are truly unique (Virginia Tech research).

Every image gets identified by a combination of a tag (like nginx:latest) and a digest (a SHA256 hash). Tags are mutable, which means latest can point to different things on different days. Digests are immutable. They always reference the exact same content.

The distinction between a Docker container and an image trips people up. An image is the blueprint. A container is a running instance of that image, with a thin writable layer added on top. When you docker run an image, Docker creates that writable layer using a copy-on-write mechanism. The original image layers stay untouched.

Why has Docker revolutionized deployment?

Explore Docker statistics: containerization adoption, DevOps transformation, enterprise usage, and how containers changed software delivery.

Discover Docker Insights →

Where Docker Images Are Stored Locally

maxresdefault Where Are Docker Images Stored? File Locations Explained

The default local storage path depends entirely on your operating system. Run docker info and look for the “Docker Root Dir” field. That tells you exactly where everything lives.

Linux Default Storage Path

On Linux, Docker stores images under /var/lib/docker/. This is the Docker root directory, and it contains subdirectories for the storage driver, image metadata, volumes, and network configuration.

The actual image layer data sits in /var/lib/docker/overlay2/ on most modern distributions. Each layer gets its own directory identified by a long content hash.

Linux leads container environments by a wide margin. According to Command Linux research, 75% of Docker containers run on Linux, and the overlay2 directory structure is what most developers interact with directly.

macOS and Docker Desktop VM Storage

macOS cannot run Linux containers natively. Docker Desktop spins up a lightweight Linux virtual machine behind the scenes, and that VM contains the actual /var/lib/docker/ directory.

The VM’s virtual disk file typically lives at:

~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw

You cannot browse Docker’s internal filesystem directly from the macOS Finder. The /var/lib/docker/ path exists only inside the VM. If you need to inspect it, you have to shell into the VM itself through Docker Desktop’s terminal.

Windows Storage With WSL 2 and Hyper-V

WSL 2 backend (default since 2020): Docker Desktop on Windows stores images inside a WSL 2 distribution. The data lives in a virtual hard disk file called ext4.vhdx, typically located at:

\wsl$docker-desktop-data

One tricky thing about this setup. The ext4.vhdx file grows as you pull and build images, but it does not automatically shrink when you remove them. Scott Hanselman documented this problem on his blog, noting his Docker WSL 2 VHD had ballooned to 47 GB before manual compaction. Portainer’s CEO reported similar findings with a 41 GB virtual disk.

Hyper-V backend (legacy): For older setups using Hyper-V, Docker stores the virtual disk under %LOCALAPPDATA%Dockerwsldata or a similar path in your AppData directory. The same thin-provisioning behavior applies.

Operating SystemDefault Storage LocationStorage Type
Linux/var/lib/docker/Direct filesystem
macOSInside Docker Desktop VM (Docker.raw)Virtual disk
Windows (WSL 2)ext4.vhdx in WSL distroVirtual hard disk
Windows (Hyper-V)AppData Docker directoryVirtual hard disk

How Docker Storage Drivers Manage Images

maxresdefault Where Are Docker Images Stored? File Locations Explained

A storage driver controls how Docker reads and writes image layers on disk. It manages the layered filesystem that makes container images work.

The overlay2 driver is the default on all actively supported Linux distributions. According to Docker’s official documentation, overlay2 requires either an ext4 or xfs backing filesystem and supports up to 128 lower OverlayFS layers natively.

Here is what happens when a container modifies a file. The storage driver searches through image layers starting from the newest, finds the file, copies it up to the container’s writable layer, then applies the change. This is the copy-on-write mechanism. The original image layer stays untouched.

You can check your active driver with docker info | grep "Storage Driver".

Why overlay2 Replaced Earlier Drivers

aufs: Was the original default on Ubuntu-based systems. Not part of the mainline Linux kernel, which made maintenance difficult. Dropped as a recommended option years ago.

devicemapper: Used block-level storage. Required complex configuration (direct-lvm mode) to run properly. The loopback mode was notoriously unstable.

btrfs and zfs: Still available for specific use cases. Both perform better for write-heavy workloads. But they require their respective filesystems, which limits portability.

The overlay2 driver won out because it balances performance, compatibility, and simplicity. It works at the file level rather than the block level, which uses memory more efficiently. Docker’s documentation notes that OverlayFS supports page cache sharing, making it a good fit for high-density environments running many containers on one host.

The 2025 Docker State of Application Development report shows that container usage in the IT industry reached 92%, up from 80% in 2024. The vast majority of those containers are running on overlay2.

Docker Image Layer Structure on Disk

maxresdefault Where Are Docker Images Stored? File Locations Explained

Look inside /var/lib/docker/overlay2/ and you will see directories with long hexadecimal names. Each one represents a layer.

Every layer directory contains several subdirectories:

  • diff/ holds the actual filesystem changes introduced by that layer
  • merged/ is the unified view combining all lower layers with the current one
  • work/ is used internally by OverlayFS for atomic operations
  • lower is a file that references parent layer IDs

There is also a special l/ directory (lowercase L) containing shortened symbolic links to each layer. Docker uses these abbreviated identifiers to avoid hitting the mount command’s page size limit for arguments.

You can trace the full layer chain of any image by running docker image inspect <image>. The output includes the image manifest, config JSON, and the ordered list of layer digests. Each digest is a SHA256 hash computed from the layer’s contents, and this is what Docker calls content-addressable storage.

Run docker history <image> and you will see each layer’s creation command and size. This is useful for debugging bloated images. You will often find layers where a RUN instruction installs packages and then a later RUN removes them, but both layers still exist and consume space. That is why multi-stage builds matter for keeping image sizes down.

A word of caution. Docker’s documentation explicitly warns against modifying anything inside /var/lib/docker/ directly. These directories are managed entirely by Docker, and manual changes can corrupt your images.

Where Docker Images Are Stored Remotely

Local storage is only half the story. Images get pushed to and pulled from remote registries, and those registries handle distribution, versioning, and access control.

Docker Hub and Public Registries

maxresdefault Where Are Docker Images Stored? File Locations Explained

Docker Hub is the default public registry. When you run docker pull nginx, Docker looks for that image on Docker Hub unless you specify a different registry.

The scale is staggering. According to Contrary Research, Docker Hub had over 17 million developers and 26 million monthly active IPs accessing 15 million repositories as of March 2024. Pull volumes reached 25 billion per month at that point.

Docker Hub enforces rate limits for unauthenticated and free-tier users. Paid subscriptions (Pro, Team, Business) get unlimited pull rates. Each layer upload is capped at 10 GB per layer.

Private and Self-Hosted Registries

Most production environments do not rely solely on Docker Hub. Teams use private registries that sit closer to their infrastructure and offer tighter security controls.

Amazon ECR: Integrates natively with AWS services. Commonly paired with EKS for Kubernetes workloads.

Google Artifact Registry: The successor to Google Container Registry. Supports multiple artifact types beyond just container images.

Azure Container Registry: Ties into Azure DevOps and AKS. Offers geo-replication for global teams.

GitHub Container Registry: Tightly connected to GitHub repositories and GitHub Actions workflows. Good for teams already using GitHub for source control.

You can also run a self-hosted registry using Docker’s open-source distribution image. The command is straightforward: docker run -d -p 5000:5000 registry:2. Behind the scenes, self-hosted registries support configurable storage backends, including Amazon S3, Google Cloud Storage, Azure Blob Storage, and local filesystem storage.

When you docker push an image, Docker uploads each layer individually. The registry checks if it already has a layer with that digest. If so, it skips the upload. This is why pushing incremental changes to a container registry is fast, since only new or modified layers need to transfer.

How to Change the Default Docker Image Storage Location

Running out of disk space on your root partition is the most common reason developers move Docker’s storage. Took me a while to realize this the first time it happened, but the fix is actually simple.

Changing the Data Root on Linux

Edit (or create) /etc/docker/daemon.json and add the data-root option:

{ "data-root": "/mnt/docker-data" } `

Before restarting the Docker daemon, move existing data to the new location with rsync -aP /var/lib/docker/ /mnt/docker-data/. Then restart Docker.

Some teams use a symlink instead. Stop Docker, move the directory, create a symlink from /var/lib/docker to the new path. It works, but the daemon.json approach is cleaner and officially supported.

Changing Storage in Docker Desktop

On macOS and Windows, Docker Desktop provides a GUI setting. Go to Settings, then Resources, then Disk image location. You can pick a new path and Docker Desktop handles the migration.

Docker Desktop on Windows using WSL 2 defaults to a 250 GB virtual disk limit. If you work with large images regularly (machine learning images can easily exceed 10 GB each), you might hit that ceiling. The WSL documentation from Microsoft explains how to resize the virtual disk, but it is a multi-step process involving diskpart.

The application container market hit $5.85 billion in 2024 according to market research, projected to grow to $31.5 billion by 2030. As container workloads scale, storage management becomes more than a convenience issue. Getting your configuration management right from the start prevents painful migrations later.

How to List and Inspect Stored Docker Images

maxresdefault Where Are Docker Images Stored? File Locations Explained

You have images eating disk space and you are not sure what is there. Docker gives you several commands to figure that out.

docker images (or docker image ls) lists every image on your local system. You get the repository name, tag, image ID, creation date, and size. Quick and readable.

docker system df breaks down total disk usage across four categories: images, containers, local volumes, and build cache. It also shows you how much is reclaimable. One developer reported seeing 51.98 GB consumed by 188 images, with 75% of that reclaimable (Blacksmith research).

docker image inspect goes deeper. It outputs the full JSON metadata for an image, including layer digests, environment variables, entry point, exposed ports, and creation timestamps.

docker history shows each layer’s Dockerfile command and individual size. This is the command you want when debugging why an image is unexpectedly large.

One thing that trips people up: the size reported by docker images is the virtual size, not the actual disk footprint. Shared layers between images are counted multiple times in that number. Use docker system df -v for the verbose view that breaks out shared versus unique size per image.

How to Clean Up Stored Docker Images

Docker does not clean up after itself by default. Stopped containers, dangling images, orphaned volumes, and build cache all pile up quietly until your disk runs out of space.

Jeff Triplett documented reclaiming 127.5 GB from a single docker system prune command. That is not unusual for developers running Docker daily over months without cleanup.

Pruning Commands

CommandWhat It RemovesRisk Level
docker image pruneDangling (untagged) images onlyLow
docker image prune -aAll unused imagesMedium
docker system pruneStopped containers, unused networks, dangling images, build cacheMedium
docker system prune -a --volumesEverything above plus all unused images and volumesHigh

The difference between docker image prune and docker image prune -a is significant. Depot research shows you might reclaim 2.7 GB with the default command but 22 GB with the -a flag, since it removes all images not tied to a running container.

Build Cache: The Hidden Disk Consumer

Build cache is the one most people forget about. Docker caches every build step to speed up subsequent builds, but those cached layers accumulate fast.

Run docker builder prune to clear it. One cleanup session documented by Triplett freed 31.29 GB of build cache alone.

If you are using Docker Compose for local development, build cache grows even faster because you are likely rebuilding multiple services regularly. Setting up a scheduled cleanup (a cron job or a build pipeline step) is worth the five minutes it takes.

Manual Removal

For surgical cleanup, docker rmi <imageid> removes a specific image. You can also filter with docker image prune –filter “until=240h” to remove images older than 10 days.

A good habit: run docker system df once a week. It takes two seconds and tells you exactly where your disk space went.

Docker Image Storage in Kubernetes and Container Runtimes

maxresdefault Where Are Docker Images Stored? File Locations Explained

Kubernetes stopped using Docker as its container runtime in version 1.24. The dockershim component was removed, and clusters moved to CRI-compliant runtimes like containerd and CRI-O.

This changes where images end up on disk.

containerd Image Storage

Default path: /var/lib/containerd/

containerd stores images using its own content store and snapshotter mechanism instead of Docker’s overlay2 directory structure. According to Command Linux data, containerd adoption jumped from 23% to 53% year-over-year, reflecting the post-dockershim migration.

Use crictl images instead of docker images to list images on containerd nodes. The ctr tool also works but is intended for low-level debugging, not daily use.

CRI-O Image Storage

Default path: /var/lib/containers/storage/

CRI-O was built specifically for Kubernetes. It is lighter than containerd and follows the OCI standard strictly. Red Hat OpenShift uses CRI-O by default.

CRI-O reached graduated status in the CNCF alongside containerd, confirming both as production-ready runtimes for container workloads.

Kubernetes Image Garbage Collection

Kubernetes handles image cleanup automatically at the node level through the kubelet. Two thresholds control this behavior:

  • imageGCHighThresholdPercent: triggers cleanup when disk usage exceeds this value (default 85%)
  • imageGCLowThresholdPercent: cleanup stops once disk usage drops below this (default 80%)

The kubelet checks for unused images every five minutes and removes them oldest-first. According to the Kubernetes documentation, you should avoid external garbage collection tools because they can break kubelet’s expected state.

Image pull policies also affect storage. Setting imagePullPolicy: IfNotPresent caches images on the node after the first pull. Always checks the registry every time, which adds network overhead but keeps images fresh. Never only uses images already present locally.

Docker Image Storage Limits and Performance

Storage problems are usually not about Docker itself. They are about the filesystem underneath it, the registry limits above it, and the image sizes in between.

Filesystem Requirements for overlay2

The overlay2 driver needs either ext4 or xfs as the backing filesystem. If you are using xfs, the dtype feature must be enabled (verify with xfsinfo and check that ftype=1).

Running overlay2 on an xfs filesystem without dtype support will cause Docker to log warnings. Future Docker versions will make this a fatal error.

Docker Desktop Disk Limits

Docker Desktop on Windows defaults to a 250 GB virtual disk for WSL 2. macOS Docker Desktop uses a Docker.raw file that grows dynamically but can be capped in the GUI settings.

Both platforms suffer from the same issue: the virtual disk file grows as you use Docker but does not shrink when you delete images. Compaction requires manual steps. On Windows, you need to shut down WSL and run Optimize-VHD or use diskpart.

Registry Limits and Image Size

Docker Hub enforces a 10 GB per layer upload limit. No documented absolute image size cap exists, but practical limits come from network timeouts and client memory during push and pull operations.

Gartner estimated that over 95% of new digital workloads would deploy on cloud-native (mostly containerized) platforms by 2025. That kind of volume makes image size a real cost factor, since every pull transfers data across a network.

Keeping images small starts at build time. Use multi-stage builds to separate build dependencies from the final runtime image. Add a .dockerignore file to exclude unnecessary files from the build context. Pick a minimal base image like Alpine (about 5 MB) instead of a full Ubuntu image (roughly 77 MB).

Teams doing continuous integration and continuous deployment feel image size most acutely. Every pipeline run that pulls a 2 GB image instead of a 200 MB one adds minutes to deployment times and dollars to cloud storage bills. Applying semantic versioning to your image tags also helps, since it prevents the ambiguity of :latest and makes it clear which image version is running where.

FAQ on Where Are Docker Images Stored

What is the default storage location for Docker images on Linux?

Docker stores images under /var/lib/docker/ on Linux. The actual layer data sits inside the overlay2 subdirectory. Run docker info and check the "Docker Root Dir" field to confirm your system's path.

Where are Docker images stored on macOS?

Docker Desktop runs a Linux VM on macOS. Images live inside that VM’s filesystem, with the virtual disk file typically located at ~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw.

Where does Docker Desktop store images on Windows?

On Windows with WSL 2, Docker stores images inside an ext4.vhdx virtual hard disk. You can find it under the docker-desktop-data WSL distribution. Hyper-V setups store it in your AppData directory instead.

How do I check how much disk space Docker images are using?

Run docker system df for a quick breakdown of disk usage across images, containers, volumes, and build cache. Add the -v flag for a detailed per-image view showing shared versus unique layer sizes.

What storage driver does Docker use for images?

The overlay2 driver is the default on all supported Linux distributions. It uses a union filesystem to layer image data efficiently. Older drivers like aufs and devicemapper are no longer recommended.

How do I change where Docker stores images?

Edit /etc/docker/daemon.json and set the “data-root” option to your preferred path. Restart the Docker daemon after moving existing data with rsync. Docker Desktop users can change this through the Settings GUI.

Where are Docker images stored remotely?

Remote images live in container registries. Docker Hub is the default public registry. Private options include Amazon ECR, Google Artifact Registry, Azure Container Registry, and self-hosted registries using Docker’s open-source distribution image.

How do I free up disk space from unused Docker images?

Run docker image prune to remove dangling images. Use docker system prune -a for a more aggressive cleanup that removes all unused images, stopped containers, and build cache at once.

Where does Kubernetes store container images?

Kubernetes nodes store images through their container runtime. containerd uses /var/lib/containerd/ and CRI-O uses /var/lib/containers/storage/. The kubelet manages automatic image garbage collection based on disk usage thresholds.

Why does Docker keep using disk space after I delete images?

Build cache and stopped containers persist even after image removal. On Windows, the WSL 2 virtual disk file grows but does not automatically shrink. Run docker builder prune and compact the VHDX file manually to reclaim space.

Conclusion

Knowing where Docker images are stored gives you direct control over disk usage, build performance, and production environment reliability. The /var/lib/docker/ directory on Linux, the virtual disk files on macOS and Windows, and the remote registries holding your pushed images all play distinct roles in the container image lifecycle.

Storage drivers like overlay2 handle the layered filesystem mechanics. Kubernetes runtimes like containerd and CRI-O store images in their own paths with their own garbage collection rules.

Run docker system df` regularly. Prune what you do not need. Move your data root before the disk fills up, not after.

Getting image storage right is a small effort that prevents real headaches in your DevOps workflow down the line.

50218a090dd169a5399b03ee399b27df17d94bb940d98ae3f8daff6c978743c5?s=250&d=mm&r=g Where Are Docker Images Stored? File Locations Explained
Related Posts