Skip to content
Back to blog

Docker Volumes Explained: Named, Bind, and tmpfs Storage

July 6, 20265 min read

Containers are ephemeral by design — when you remove one, its filesystem disappears with it. That is fine for stateless apps, but databases, uploaded files, and logs need to survive restarts and redeploys. Docker volumes solve this by storing data outside the container layer.

This guide explains why volumes matter, the three storage types (named volumes, bind mounts, tmpfs), how to share data between containers, and the commands you use daily. If you have ever lost database data after `docker rm`, this is the fix.

ContainerDocker VolumePersistent DataData survives container restarts and removal when stored in a volume
Volumes store data outside the container filesystem

Why Docker Volumes?

A container filesystem is a thin writable layer on top of an image. Anything written inside the container lives in that layer. When the container is deleted, the layer is deleted too — along with your database files, uploads, and logs.

A volume stores data on the host (or in Docker's managed storage area) and mounts it into the container at a path like `/var/lib/mysql`. The container can read and write the volume, but the data belongs to the volume — not the container. Delete the container, start a new one, mount the same volume, and your data is still there.

Without volumeEphemeralContainer deletedData deletedWith volumePersistentContainer deletedData remains safe
Without a volume, deleting the container deletes the data

Quick reference

  • Without volume: container deleted → data deleted.
  • With volume: container deleted → data remains safe.
  • Volumes survive container restarts, upgrades, and replacements.
  • Images are immutable; volumes hold mutable runtime state.
  • Use volumes for databases, file uploads, and application logs.
  • Container storage is for temporary cache and build artifacts only.

Remember this

Volumes decouple data lifetime from container lifetime — essential for anything that must persist.

Named Volumes

Named volumes are created and managed by Docker. You give them a name (`mysql_data`), and Docker stores the data in a directory on the host that you do not need to manage manually. Mount a named volume into a MySQL container at `/var/lib/mysql`, and database files persist across container replacements.

Named volumes are the default choice for production databases and any data you want Docker to manage cleanly. They work across platforms, back up easily with `docker run --volumes-from`, and appear in `docker volume ls`. Docker handles permissions and storage location.

MySQL\nContainermysql_data\nVolumeDatabase files\nUploads · LogsManaged by Docker · easy to reuse across container replacements
Named volume: Docker-managed storage for databases and production data

Quick reference

  • Created with: docker volume create mysql_data
  • Mounted with: -v mysql_data:/var/lib/mysql
  • Managed by Docker — no host path required.
  • Best for: PostgreSQL, MySQL, Redis persistence, uploads.
  • Survives docker rm on the container.
  • Reusable: new container mounts same volume by name.

Remember this

Named volumes are Docker-managed persistent storage — the production default for databases.

Bind Mounts and tmpfs

Not every mount is a named volume. A bind mount maps a specific host directory into the container — for example `-v ./src:/app/src`. Edit files on your laptop and see changes instantly inside the container. Bind mounts are ideal for local development where you want live code reload without rebuilding the image.

A tmpfs mount stores data in memory (RAM), not on disk. It disappears when the container stops. Use tmpfs for temporary files, sensitive secrets you do not want written to disk, or high-speed scratch space. tmpfs mounts are fast but not persistent.

Named VolumeDocker-managedBest for databasesProduction dataReusable across runsBind MountHost folderMaps host pathGreat for devLive code reloadtmpfs MountIn-memoryGone when stoppedSecrets / temp filesFast, no disk I/O
Three Docker storage types: named volume, bind mount, tmpfs

Quick reference

  • Bind mount: host path → container path (-v /host:/container).
  • Bind mount: host changes appear inside container immediately.
  • Bind mount: risky in production — host path coupling.
  • tmpfs: data lives in RAM — gone when container stops.
  • tmpfs: good for secrets, temp files, sensitive caches.
  • Named volume > bind mount for production database data.
Before
Bind mount — development workflow
1# Live-reload your app code during development2docker run -v $(pwd)/src:/app/src -p 3000:3000 myapp
After
tmpfs — secrets that never touch disk
1# Mount sensitive data in memory only2docker run --tmpfs /run/secrets:rw,noexec,nosuid myapp

Remember this

Bind mounts for dev convenience; tmpfs for ephemeral secrets; named volumes for production persistence.

Bind Mounts in Practice

Bind mounts create a direct bridge between a host folder and a container path. Your project directory on disk becomes `/app` inside the container. Tools like Docker Compose use bind mounts heavily in development: mount source code, run the app in a container, edit files in your IDE, and the running process picks up changes.

The trade-off is coupling. The container now depends on a specific host path existing. That path differs between developers' machines and does not exist in CI or production the same way. Never bind-mount production database directories — use named volumes instead.

Host Folder\n./srcContainer\n/app/srcEdit files on the host — changes appear instantly inside the container
Bind mount: host folder mapped directly into the container

Quick reference

  • Syntax: -v /absolute/host/path:/container/path
  • Relative paths work: -v ./data:/app/data
  • Read-only bind: append :ro to the mount.
  • Compose: volumes: - ./src:/app/src in service definition.
  • Watch out for file permission mismatches (UID/GID).
  • Production: prefer named volumes over bind mounts.

Remember this

Bind mounts trade portability for dev speed — perfect locally, avoid in production.

Sharing Volumes Between Containers

Multiple containers can mount the same volume simultaneously. An app container writes data to `shared_data`; a backup container mounts the same volume and copies files to S3. A sidecar pattern uses this for log shipping or metrics collection.

Docker handles concurrent access, but your application must still handle file locking if multiple writers touch the same files. For databases, only one container should write to the volume at a time — run a single database instance per named volume.

App\nContainerBackup\nContainershared_data\nVolumeBoth containers read and writethe same persistent data
Multiple containers can mount the same volume

Quick reference

  • Same volume name in -v flag on multiple containers.
  • App + backup sidecar is a common pattern.
  • Compose: define volume once, reference in multiple services.
  • Read-only share: mount :ro on the backup container.
  • One writer per database volume — no concurrent DB containers.
  • docker run --volumes-from copies mounts from another container.

Remember this

One volume, many containers — great for backups and sidecars, but coordinate write access.

Essential Volume Commands

Docker provides a small CLI for volume management. List all volumes with `docker volume ls`. Create one explicitly with `docker volume create mydata` before running a container, or let Docker auto-create it on first mount. Inspect a volume to see its mount point on the host with `docker volume inspect mydata`.

Remove a single volume with `docker volume rm mydata` — only when no container is using it. Clean up all unused volumes at once with `docker volume prune` (careful: this deletes data). Remember: deleting a container does not delete its volumes unless you pass `--volumes` to `docker rm` or `docker compose down -v`.

Quick reference

  • docker volume ls — list all volumes.
  • docker volume create mydata — create named volume.
  • docker volume inspect mydata — show mount point and driver.
  • docker volume rm mydata — delete one volume.
  • docker volume prune — remove all unused volumes.
  • docker rm -v — remove container AND its anonymous volumes.
  • docker compose down -v — remove compose volumes too.

Remember this

Delete container ≠ delete volume — use docker volume rm or prune explicitly.

Key takeaway

Share:

Docker volumes are how you add persistence to ephemeral containers. Use named volumes for databases and production data, bind mounts for local development with live reload, and tmpfs for secrets and temporary files that should never touch disk. Mount volumes at the right path, share them between containers when needed, and remember that removing a container leaves the volume intact — which is usually exactly what you want.

Related Articles

Docker and Kubernetes show up in the same sentence constantly, but they operate at different layers. Docker is a **conta

Read

Microservices are not a single tool — they are an ecosystem. You need containers to package services, databases to store

Read

You deployed your app to Kubernetes and opened the URL — but what actually happens between the browser and your containe

Read

Explore this topic

Keep learning

Follow a structured path or browse all courses to go deeper.