Skip to main content
Docker Volume bind mount Delete a container and whatever you wrote into its writable layer is gone. To keep data, put it outside the container. This page makes the four destinations clear. Toggle the four modes below to see where data actually lands and whether it survives deletion:

Without a mount, data is in the container writable layer

A container has a writable layer on top of the read-only image layers. Without a mount, files you write land there, using copy-on-write (CoW): editing an existing file copies the whole file from the read-only layer up to the writable layer first, then edits the copy.
  • Changing one byte of a 1 GB file still copies the whole file first, so write-heavy work is noticeably slow.
  • The writable layer follows the container lifecycle; docker rm wipes it all.
So databases, data you need to keep, and high-I/O workloads should never live only in the writable layer.

Comparing the three mount types

A named volume’s physical location

On Linux:
Under the WSL 2 backend, that path is inside the docker-desktop-data WSL VM, not on the Windows filesystem, so you cannot browse into it from File Explorer. To read volume contents:

bind mount: -v vs --mount

Two syntaxes for the same thing, but --mount is explicit and officially preferred:
The -v relative-path trap: -v mydata:/app/data (no leading slash) is treated as “create a named volume called mydata”, not a bind mount. To be sure it is a bind mount, use an absolute path or the explicit --mount type=bind.

Anonymous volumes and the Dockerfile VOLUME trap

-v with only a container path and no name creates a random-UUID anonymous volume. The Dockerfile VOLUME instruction also auto-creates an anonymous volume mounted at that path on docker run.
At docker run an anonymous volume mounts over /app, shadowing the node_modules the image layer installed, and the app will not start. Fix: do not declare VOLUME on a path that gets shadowed, or skip VOLUME and mount explicitly at docker run / Compose. A container deleted without --rm leaves a dangling anonymous volume; clear it with docker volume prune.

docker volume commands

WSL 2 mount performance (important)

High-I/O data (source code, node_modules, database files) should sit on the WSL 2 Linux filesystem and be bind-mounted from there. Do not mount from /mnt/c (Windows paths):
Official guidance: bind mounts from the Windows filesystem are noticeably slower, and inotify events only work on the Linux filesystem, so mounting /mnt/c breaks hot reload (Vite, webpack, nodemon) because file-change events never fire. For high-I/O cases, prefer named volumes or bind mounts originating on the WSL 2 Linux side.

Next

Reference: docs.docker.com/engine/storage