# Where Docker Stores Images, and Why You Cannot Just Delete Them

> The real on-disk location of Docker images on Linux, macOS and Windows, why the directory is unreadable by design, and how to shrink the Docker Desktop disk image.

Source: https://latchkey.dev/learn/ci-explained/where-docker-stores-images  
Updated: 2026-08-31

On Linux, images live under /var/lib/docker. On macOS and Windows they live inside a virtual disk, which is why the file is enormous and why deleting images does not shrink it.

This question is usually asked by someone who has run out of disk and wants to go in and delete something by hand. The honest answer is that the directory exists, you can find it, and you should not touch it: the layout is content-addressed and manipulating it outside Docker corrupts the image store.

What you actually want is either the path, for moving the whole thing to a bigger disk, or the reason the disk image will not shrink.

## The paths

| Platform | Location | Notes |
| --- | --- | --- |
| Linux | `/var/lib/docker` | Layers under `overlay2/`, image metadata under `image/overlay2/`. Root-owned. |
| macOS (Docker Desktop) | `~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw` | A single virtual disk file containing a Linux VM. Everything is inside it. |
| Windows (WSL 2 backend) | `%LOCALAPPDATA%\Docker\wsl` | A `.vhdx` virtual disk, same idea as the macOS file. |
| Any platform, authoritative | `docker info --format "{{.DockerRootDir}}"` | Ask the daemon rather than guessing. This is the only answer that survives a custom configuration. |

## Why the directory is not browsable in any useful way

Images are stored as content-addressed layers, so a directory under `overlay2/` is named by a hash and shared between every image that contains that layer. There is no folder per image, deleting one directory can break several images at once, and the daemon keeps its own index that will not know you did it. Use `docker image inspect` and `docker system df -v` to find out what is large, and prune commands to remove it.

## The Docker Desktop file that will not shrink

On macOS and Windows the virtual disk grows as you use it and does not automatically give the space back when you delete images, because freeing space inside the VM leaves a hole in the file rather than making it smaller. Pruning inside Docker is still the right first step, and then the disk image has to be compacted separately.

- Prune first, inside Docker: `docker system prune -a --volumes` and `docker builder prune -a`. Nothing else can help until the space is free inside the VM.
- Then compact from Docker Desktop, under Settings, Resources, Advanced. Recent versions reclaim automatically after a prune; older ones need the disk reset.
- The nuclear option is Settings, Troubleshoot, Reset to factory defaults, which deletes every image, container and volume and recreates the disk at its minimum size.

> The virtual disk also has a maximum size set in Docker Desktop settings, which is a cap and not an allocation: raising it does not consume disk immediately, and lowering it below current usage is not possible without a reset.

## Moving the store to a different disk

```Relocating the Docker root directory
# /etc/docker/daemon.json, Linux
{
  "data-root": "/mnt/bigdisk/docker"
}

sudo systemctl stop docker
sudo rsync -aP /var/lib/docker/ /mnt/bigdisk/docker/
sudo systemctl start docker
```

> Stop the daemon before copying. Copying a live image store gives you a corrupt one, and this is the one situation where touching the directory directly is correct.

## Applying this to your pipeline

- Measure before changing. Most CI optimisation targets the wrong step because the slow one is assumed rather than timed.
- Cache what is expensive to produce and cheap to validate, and key the cache to the exact tool version.
- Fail fast: run the cheapest checks that can reject a change first, so an expensive job never starts on code that cannot pass.
- Prefer determinism over speed when they conflict. A fast pipeline nobody trusts gets re-run, which is slower than a slow one that is believed.

## FAQ

### Where are Docker images stored?

On Linux, under `/var/lib/docker`, with the layers themselves in `overlay2/`. On macOS and Windows they are inside a single virtual disk file used by the Docker Desktop VM. Run `docker info --format "{{.DockerRootDir}}"` for the authoritative answer on any machine.

### Can I delete files in /var/lib/docker to free space?

No. Layers are content-addressed and shared between images, and the daemon maintains an index that will not know what you removed, so hand-deleting corrupts the image store. Use `docker image prune -a` and `docker builder prune -a` instead.

### Why is Docker.raw so large?

It is the whole Docker VM: every image, container, volume and build cache entry lives inside that one file. It grows as you use Docker and does not shrink automatically when you delete things, because freeing space inside the VM leaves the file the same size.

### How do I shrink the Docker Desktop disk image?

Prune inside Docker first, then compact the disk from Docker Desktop under Settings, Resources, Advanced. Pruning alone frees space inside the VM but does not return it to the host until the disk is compacted.

### How do I move Docker to another drive?

Set `data-root` in `/etc/docker/daemon.json` to the new path, stop the daemon, copy the existing directory across with `rsync -aP`, then start it again. The daemon must be stopped for the copy or you will move a half-written image store.

---

Latchkey runs CI/CD that repairs its own failures. Agent entry points: https://latchkey.dev/agent.txt, https://latchkey.dev/openapi.json, https://latchkey.dev/llms.txt
