Docker Volume — Persistent Storage That Outlives Containers
What Is a Docker Volume in Simple Terms?
Everything written inside a container is lost when the container is removed. A Docker volume is storage that lives outside the container — managed by Docker, stored on the host filesystem, and attached to the container at a specific path. The container can read and write to it normally, but the data persists even after the container is deleted.
Bash
Without volume: Container runs, writes data to /app/data docker rm container Data is GONE permanently With volume: Container runs, writes data to /app/data /app/data is mounted from volume postgres-data docker rm container Volume postgres-data still exists with all data New container mounts same volume Data is still thereVolume vs Bind Mount vs tmpfs
Bash
Docker Volume (recommended for production data): -v postgres-data:/var/lib/postgresql/data Stored at: /var/lib/docker/volumes/postgres-data/_data Managed by Docker Survives container removal Portable between containers Bind Mount (for development): -v /host/path:/container/path Uses actual host filesystem path Changes on host appear in container immediately Good for: code hot-reload, config injection tmpfs (for temporary sensitive data): --tmpfs /tmp In-memory only — fastest I/O Lost when container stops Good for: secrets, caches that should not persistWorking With Volumes
Bash
# Create a named volumedocker volume create postgres-data # Use in docker rundocker run -d \ --name postgres \ -v postgres-data:/var/lib/postgresql/data \ -e POSTGRES_PASSWORD=secret \ postgres:15 # List volumesdocker volume ls# DRIVER VOLUME NAME# local postgres-data # Inspect — find where data is stored on hostdocker volume inspect postgres-data# "Mountpoint": "/var/lib/docker/volumes/postgres-data/_data" # Remove a volume (permanent data deletion)docker volume rm postgres-data# Error if a container is using it # Remove all unused volumesdocker volume prune# WARNING: deletes volumes not used by any container # In Docker Composeservices: postgres: volumes: * postgres-data:/var/lib/postgresql/data volumes: postgres-data: # top-level declaration — Docker manages itBacking Up and Restoring Volumes
Bash
# Backup to tar filedocker run --rm \ -v postgres-data:/source:ro \ -v $(pwd):/backup \ alpine \ tar czf /backup/postgres-backup.tar.gz -C /source . # Restore from tar filedocker volume create postgres-data-restoreddocker run --rm \ -v postgres-data-restored:/target \ -v $(pwd):/backup:ro \ alpine \ tar xzf /backup/postgres-backup.tar.gz -C /targetPLACEMENT PRO TIP**Tip:** Named volumes are the right choice for any data that must persist. Anonymous volumes (created without a name: `-v /var/lib/postgresql/data`) also persist but are hard to manage — they get random IDs and are difficult to back up or migrate. Always name your volumes.
COMMON MISTAKE / WARNING**Common Mistake:** Storing database data in the container's own filesystem instead of a volume. The container filesystem uses OverlayFS which is slower for database I/O and is deleted with the container. Always use `-v named-volume:/db/data/path` for any database container.