A container image is designed to be reproducible, while application data often needs a different lifecycle. If a database writes only to its container's writable layer, replacing that container can discard the data. If a production service bind-mounts an arbitrary host directory, the data may persist but the deployment becomes tightly coupled to one machine. Docker volumes, bind mounts, and tmpfs mounts exist because those requirements are not the same.

Start with the container writable layer
Every running container gets a writable layer above its read-only image layers. It is convenient for disposable runtime changes, tests, and caches that can be rebuilt. It is a poor default for durable state because the layer belongs to that container. Recreating the service creates a new writable layer.
Writing heavily to that layer can also be less suitable than a mounted storage mechanism. More importantly, it blurs the operational contract: a replacement should be safe, but irreplaceable data hidden inside the old container makes replacement dangerous.
Compare the three mount types
| Mount | Managed by | Best fit | Main trade-off |
|---|---|---|---|
| Named volume | Docker | Durable application data such as a local database | Backup and migration still need an explicit process |
| Bind mount | Host path chosen by you | Source code, local configuration, or files shared with host tools | Host layout, permissions, and security become part of deployment |
| tmpfs | Host memory through Docker | Temporary scratch data that must not persist with the container | Consumes memory and disappears when the container stops |
A named volume survives removal of the container that used it unless the volume itself is deleted. Docker manages its host location; applications should access it through a mount rather than editing Docker's internal storage directories. A bind mount deliberately exposes an existing host path. That is excellent for a local editing loop and risky when an unexpected host path or writable mount can alter sensitive files.
A tmpfs mount keeps files outside the container's persistent writable layer and disappears when the container stops. It is useful for bounded temporary data, but it is not a secret-management system and it needs a memory budget.
Express the storage contract in Compose
services:
app:
build: ./app
volumes:
- type: bind
source: ./config
target: /app/config
read_only: true
- type: tmpfs
target: /tmp
tmpfs:
size: 67108864
db:
image: postgres:17-alpine
volumes:
- type: volume
source: pgdata
target: /var/lib/postgresql/data
volumes:
pgdata:
The long syntax makes intent visible. Configuration is a read-only bind mount, temporary files receive a 64 MiB tmpfs budget, and PostgreSQL receives a Docker-managed volume. The actual database credentials should come from an approved secret path rather than this file.
Be careful when mounting over a non-empty directory in an image. The mount obscures the files that were already present at that target while the mount is active. A local bind mount of an empty host directory over /app can make an otherwise valid image appear to have lost its application.
Persistence is not a backup
A volume protects data from ordinary container replacement. It does not protect against an accidental delete, corrupt write, host failure, ransomware, or an operator running docker compose down -v. A backup needs separate retention, integrity checks, access controls, and a tested restoration procedure.
For PostgreSQL, prefer database-aware tooling that produces a consistent logical backup:
docker compose exec -T db \
pg_dump --format=custom --username=app --dbname=app \
> app-backup.dump
The redirection above runs in the host shell, so the dump file is written on the host. Protect it as sensitive data. Test restoration in an isolated environment before relying on it. Archiving raw database files while the database is actively writing is not automatically application-consistent.
Make the choice from the workload
- Database files: use a volume for local Compose persistence, plus database-native backup and recovery.
- Source code during development: use a bind mount when host and container intentionally share edits.
- Static production application code: bake it into an immutable image instead of mounting a developer directory.
- Read-only configuration: use a narrowly scoped read-only mount or the platform's configuration mechanism.
- Temporary scratch space: use a size-bounded tmpfs only when memory-backed ephemeral storage fits the workload.
Common pitfalls
- Assuming a named volume is included in source control or image backup.
- Using
down -vwithout confirming which project volumes it removes. - Giving a container a writable bind mount to a broader host directory than it needs.
- Ignoring UID, GID, and file-mode differences between the host and container.
- Putting unbounded temporary output in tmpfs until the host experiences memory pressure.
- Copying raw live database files instead of using a consistent backup method.
Storage works together with Compose networking: a database can be recreated with a new IP and reconnect through the stable db name while its volume preserves state. For production lifecycle behavior, continue with Vikas's Docker Compose health checks and startup order guide.
Frequently asked questions
Does a volume survive docker compose down?
Named volumes normally remain after docker compose down. Adding -v requests volume removal, so review the exact project and backup status before using it.
Are bind mounts only for development?
No, but development is their clearest use case. Production bind mounts can be valid for controlled host files, provided portability, permissions, scope, and operational ownership are intentional.
Is tmpfs automatically safe for secrets?
No. It avoids persistent container storage, but processes with sufficient access can still read the data. Use proper secret distribution, least privilege, rotation, and auditing.
What do the official docs recommend?
Review Docker's storage overview, its volume guidance, and the bind-mount considerations.
Practice the storage decisions
The linked mock asks you to classify real storage cases and connects them with networking, health checks, Kubernetes resources, and rollouts.
A practical assessment covering Docker Compose health checks, container DNS and storage, Kubernetes probes, resources, OOM diagnostics, and safer rolling updates. Start the trivia-style player right inside the article.Docker and Kubernetes Production Readiness Mock Test

Practical takeaway: a mount is a lifecycle decision. State what must persist, who must access it, what can be rebuilt, and how recovery will be tested before choosing the syntax.


Discussion
0 comments
Ask a question or share what stood out to you.