Docker Volumes vs Bind Mounts vs tmpfs
Containers are disposable, but data often isn't. Docker offers three ways to give a container storage beyond its own temporary layer.
Named volumes
docker volume create pgdata
docker run -d -v pgdata:/var/lib/postgresql/data postgres:17
docker volume ls
docker volume inspect pgdata
- Managed by Docker, stored in Docker's own area on the host.
- The best choice for databases and any data that must outlive the container.
- Works the same on Linux, macOS and Windows, and performs well on Docker Desktop.
Bind mounts
docker run --rm -it -v "$PWD":/app -w /app node:22 npm run dev
docker run -v "$PWD/nginx.conf":/etc/nginx/nginx.conf:ro nginx # :ro = read-only
- Map a specific host path into the container.
- Ideal for development (edit code on the host, run it in the container) and for injecting config files.
- Depend on the host's directory layout and file permissions, so avoid them for production data.
tmpfs mounts
docker run --read-only --tmpfs /tmp:size=64m my-api
- Stored in memory, gone when the container stops.
- Good for scratch files and sensitive temporary data, and pairs well with read-only root filesystems.
Backing up a volume
docker run --rm -v pgdata:/data -v "$PWD":/backup alpine \
tar czf /backup/pgdata-$(date +%F).tar.gz -C /data .
For databases, prefer the database's own tools (pg_dump, mysqldump); copying files from a running database can produce a corrupt backup.
Permission problems
"Permission denied" on a mount usually means the container user's UID doesn't own the files. Match the UID (--user $(id -u):$(id -g) for bind mounts in development) or set ownership in the image with chown.
Was this article helpful?
Comments
No comments yet. Have a question or a tip? Be the first to share it.