Docker Disk Cleanup Without Losing Your Database Volumes

Docker labels your database volume unused, and deleting a big image barely moves the disk number. What is safe to prune, and what is actually taking the space?

Docker Disk Cleanup Without Losing Your Database Volumes
TLDR
  • Measure shared image data and the selected builder’s cache before choosing a cleanup command.
  • Detached database volumes can remain valuable even when Docker calls them unused.
  • On Mac, check actual disk-image consumption; reducing its size limit deletes the existing image.

Start with usage, not the size of Docker.raw

A Mac user reported finding a 494GB Docker.raw file and reduced Docker Desktop's disk limit. Replies pointed out that a sparse file's displayed size can differ from its actual allocation. That distinction matters before cleanup: the largest-looking file is not necessarily consuming the amount its maximum size suggests.

There is another distinction inside Docker. Images, stopped containers, build cache, and database volumes have different purposes and deletion rules. Removing rebuildable output can recover space; removing a detached database volume removes data that a future container may still need.

Begin with these read-only queries against the development Docker installation you intend to clean:

docker context ls
docker system df -v
docker ps -a
docker buildx du

Contexts identify Docker endpoints, including remote ones. Environment variables such as DOCKER_HOST and DOCKER_CONTEXT, or command-line connection options, can override the usual target. A terminal on your laptop does not by itself mean the commands operate on the laptop.

The verbose usage report separates shared and unique image data. Suppose two images share a 2GB base and each adds 100MB. Adding both image sizes counts the shared base twice. Deleting one image does not release a base that the other still needs. Use the report to identify which category warrants cleanup instead of estimating savings from image sizes alone.

Find the database before removing its container

ObjectWhat it holdsConsequence of removal
ImageFiles and configuration used to create containersPull or rebuild it when needed again
Container writable layerFiles changed inside that containerThose changes disappear with the container
Build cacheReusable results from earlier build stepsLater builds repeat more work
VolumeData stored independently of container lifetimeNeeded data must come from another copy or backup

A volume outlives its container. That is useful for databases, but only if the application actually stores its database in the mounted location. A database left in the container's writable layer has a different fate when that container is removed.

For a container named app-db, inspect its Mounts section. Replace the example name with the actual name from your container list:

docker inspect app-db

For a volume mount, record its Name and Destination. For a bind mount, the data lives at a host path instead. This tells you what must survive cleanup. It also gives you a concrete identity to check when the application starts again, rather than assuming that any remaining volume must be the right database.

Choose how broadly to prune images and containers

The default image prune removes dangling images: untagged images that no container references.

docker image prune

A result of 0B can mean that no image met that definition. Tagged images and build cache can still occupy substantial storage. Adding -a to image prune expands the selection to images without an associated container. A stopped container can still keep its image referenced, which is why the earlier container listing matters.

If an old test container is no longer needed, preserve any required files and remove that specific stopped container. The example below uses the placeholder name old-test:

docker rm old-test

Without force, this does not forcibly remove a running container. The broader container prune command removes all stopped containers, including ones you may have stopped only temporarily. Naming the obsolete test keeps the decision attached to a known workload.

System prune combines removal of stopped containers, unused networks, dangling images, and unused build cache. It excludes volumes by default. Its -a option broadens image selection; --volumes adds unused anonymous volumes. Adding -a alone does not add volumes to the deletion list. Adding --volumes can remove an unused anonymous volume even when it contains a database you want to keep.

Keep the confirmation prompt while choosing a scope. If the described removal is broader than intended, cancel and use the category-specific command. This is particularly useful when one Docker installation contains several unrelated projects.

Clean the builder that owns the cache

Buildx disk usage applies to the selected builder. If a project uses a separate builder, target it explicitly for both inspection and cleanup.

To find that name, run docker buildx ls. In NAME/NODE, an asterisk marks the current builder. The nodes beneath it and the DRIVER/ENDPOINT column show the connections it uses. For example, a project built on a remote endpoint can accumulate cache there while your local images occupy a different disk. Removing remote cache will not free the same number of bytes on your laptop. Match the builder name and endpoint to the storage problem before pruning.

With that builder identified, inspect its usage and then choose whether to prune:

docker buildx du --builder mybuilder
docker buildx prune --builder mybuilder --filter "until=168h"

Replace mybuilder with the real builder name. The first line inspects; the second deletes eligible cache after confirmation. Run the second only after deciding to discard older cache for that builder.

For this Buildx filter, 168 hours preserves records used within the last seven days. It is a recent-use condition, not the creation-date interpretation used by some other prune operations. Choosing a duration connects cleanup to how frequently you return to a project.

Removing cache trades storage for repeated work in later builds. A record shared with an image may lose cache metadata while its underlying layers remain necessary for that image. Records marked non-reclaimable are actively in use. Neither the cache total nor a more aggressive option guarantees an equal amount of new host free space.

Unused volumes can still contain next week's work

Docker defines an unused local volume by the absence of container references. It does not inspect the contents to decide whether they matter. Removing a project's last container can leave its database volume technically unused while you still intend to resume the project.

Current volume prune defaults to unused anonymous volumes. Adding --all includes unused named volumes too; this option requires Docker API 1.42 or later. If a named database volume survives a broad system cleanup, that can be the intended behavior. Retain it when its data is still required; reduce database contents through that application's retention and backup procedures.

Compose down normally removes project containers and networks while leaving volumes. Adding -v removes named volumes declared by the Compose file and anonymous volumes attached to containers. Volumes declared external remain outside that removal.

CommandVolume scope
docker system pruneNo volumes by default
docker system prune --volumesUnused anonymous volumes
docker volume prune --allUnused local volumes, including named ones
docker compose down -vDeclared named and attached anonymous project volumes, excluding external volumes

An anonymous volume remaining on disk does not mean the next Compose up will automatically reuse it. Compose documents that these volumes lack stable names for automatic remounting. Use a named volume or an explicit bind path for data that must be connected consistently between runs.

Reclaim host space on Docker Desktop for Mac

In Docker Desktop for Mac, Settings → Resources → Advanced shows the disk image location, maximum size, and actual consumption. Compare actual consumption before treating a large Docker.raw reading as a storage emergency.

Host reclamation can take a few minutes after cleanup. Deleting files inside a running container does not necessarily release host space automatically. Docker documents this helper for triggering reclamation on Desktop for Mac:

docker run --privileged --pid=host docker/desktop-reclaim-space

This is a privileged operation sharing the Docker host's PID namespace, so keep it scoped to the intended local Desktop endpoint. It is not a generic remote-server cleanup step.

Reducing the maximum disk-size slider is different: Docker warns that this deletes the current disk image and loses containers and images. Moving storage should likewise use Desktop's Disk image location setting, rather than moving the file directly in Finder.

Finish by repeating the original usage query against the same Docker target. When resuming the project, check that the database is attached to its intended volume and that a fresh build completes after cache removal.