What's the difference between a volume, a bind mount, and tmpfs?
Quick Answer
A volume is storage fully managed by Docker, living in Docker's own area on disk, independent of any specific host directory — the standard, recommended choice for real application data. A bind mount maps a specific path on the host's filesystem directly into the container, giving full control over where the data lives but tightly coupling it to that host's directory layout. A tmpfs mount stores data only in the host's memory (RAM), never touching disk — fast, but gone the moment the container stops.
Detailed Answer
Volumes — Docker-managed, the recommended default
docker volume create my-data
docker run -d -v my-data:/app/data myapp:1.0
Docker creates and manages the actual storage location on the host, usually under /var/lib/docker/volumes/, fully abstracted away from you. You reference it by name, like my-data, not by a specific host path. Volumes are the recommended way to persist real application data — a database's files, or uploaded content — because Docker manages their lifecycle, backup tooling, and driver options consistently, no matter how the host's own directories are laid out.
Bind mounts — an arbitrary host path, mapped directly in
docker run -d -v /home/user/my-config:/app/config myapp:1.0
# or, using the more explicit --mount syntax:
docker run -d --mount type=bind,source=/home/user/my-config,target=/app/config myapp:1.0
Maps a specific, existing path on the host directly into the container. This gives full control over exactly where the data lives on the host. It's genuinely useful for specific cases: mounting your local source code into a container for live-reload development, or sharing an existing host directory. The tradeoff: the container now depends on that exact host path existing, with the right permissions and content. That ties it tightly to one host's directory layout, which hurts portability.
tmpfs mounts — memory-only, never touches disk
docker run -d --tmpfs /app/cache myapp:1.0
Data written here lives entirely in the host's RAM. It's extremely fast, but completely lost the moment the container stops — even a plain docker stop/docker start cycle loses it, unlike a volume or bind mount. Use it for genuinely temporary data: a cache you're fine losing, or sensitive temporary data (like a decrypted secret) you'd rather never touch disk at all.
Side-by-side comparison
| Volume | Bind mount | tmpfs | |
|---|---|---|---|
| Managed by | Docker | You (an arbitrary host path) | Docker (in-memory only) |
| Survives container removal | Yes | Yes (it's just a host directory) | No — gone even on container stop |
| Portable across different hosts | Yes (referenced by name, not host path) | No (tied to that host's specific path) | N/A (never persists anywhere) |
| Typical use | Real application/database data | Local development (mounting source code), sharing a specific existing host resource | Temporary, sensitive, or performance-critical scratch data |
Why volumes are generally preferred over bind mounts in production
A bind mount ties the container's correct behavior to one host's directory structure and permissions — exactly the kind of environment-dependent coupling containers are meant to eliminate. A volume, referenced purely by name, works identically no matter which host it runs on. That's a much better fit for production, where you want the same container configuration to behave the same way everywhere.