Docker Volumes
Containers are ephemeral by default — all data written inside the container's filesystem is lost when the container is removed. Docker volumes provide persistent storage that survives container removal. Understanding the difference between named volumes (managed by Docker), bind mounts (mapping a host path into the container), and tmpfs mounts (in-memory, for secrets) is essential for correctly persisting application data.
Storage types
Docker storage options:
Named volume:
Docker manages storage in /var/lib/docker/volumes/
Portable, can be backed up with docker commands
Best for: database data, application state
Bind mount:
Maps a host directory/file into the container
Host manages the path and permissions
Best for: development (live code reload), config files
tmpfs mount:
In-memory storage, never written to disk
Lost when container stops
Best for: sensitive data (passwords, tokens) that should not persistNamed volumes
# Create a named volume:
docker volume create myapp-data
# Use volume in a container:
docker run -d --name mysql-db -v myapp-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=secret mysql:8.0
# List volumes:
docker volume ls
# Inspect a volume (shows mountpoint on host):
docker volume inspect myapp-data
docker volume inspect output
[{
"Name": "myapp-data",
"Driver": "local",
"Mountpoint": "/var/lib/docker/volumes/myapp-data/_data",
"CreatedAt": "2025-06-09T14:30:00Z"
}]
# Remove unused volumes:
docker volume prune # Removes volumes not attached to any container
Bind mounts
# Mount a specific host directory:
docker run -d --name nginx -v /var/www/mysite:/usr/share/nginx/html:ro \ # :ro = read-only
-p 80:80 nginx:alpine
# Development: mount code directory (live reload):
docker run -d --name dev-server -v /home/irfan/myapp:/app \ # Code changes reflect immediately
-p 3000:3000 node:20-alpine node /app/server.js
📝 NOTE: Bind mounts create a dependency on the host path structure. If the host path does not exist, Docker creates it (as a directory). For production, prefer named volumes for database data and only use bind mounts for config files and development code.
Volume backup and restore
# Backup a named volume to a tar archive:
docker run --rm -v myapp-data:/data -v /backup:/backup alpine tar czf /backup/myapp-data-$(date +%Y%m%d).tar.gz -C /data .
# Restore from backup to a volume:
docker run --rm -v myapp-data:/data -v /backup:/backup alpine tar xzf /backup/myapp-data-20250609.tar.gz -C /data
# Alternative: access volume data directly on host:
sudo ls /var/lib/docker/volumes/myapp-data/_data/
Conclusion
Named volumes for persistent application data, bind mounts for configuration files and development workflows. Always define volumes explicitly in your docker run command or docker-compose.yml for any data you care about — never rely on container-internal storage for anything that must survive a container recreation. Run docker volume prune periodically to clean up orphaned volumes, but inspect them first: docker volume ls to confirm they are not in use by any container.
FAQ
Is Docker Volumes important for Ubuntu administrators?+
Yes. It supports practical Ubuntu administration because it connects directly to server reliability, security, troubleshooting, or daily operations.
Should I practice this on a live server?+
Use a lab VM first. After you understand the command output and rollback path, apply the workflow carefully on real systems.
What should I do after reading this article?+
Run the practice commands, write down what each one shows, and continue to the next article in the Ubuntu roadmap.
Need help with Ubuntu administration?
Work directly with Muhammad Irfan Aslam for Ubuntu Server, Linux, cloud, Docker, DevOps, CI/CD, or infrastructure troubleshooting support.
Hire Me for Support