DevOpsLesson
DevOpsLesson

Free, comprehensive DevOps tutorials and learning roadmaps. Master Docker, Kubernetes, CI/CD, and more.

Stay Updated

Get notified about new tutorials and features.

Tutorials

  • What is DevOps?
  • Docker Tutorial
  • Terraform Tutorial
  • CI/CD Pipeline
  • All Tutorials

Roadmaps

  • DevOps Engineer
  • Cloud Engineer
  • SRE Path
  • All Roadmaps

Company

  • About Us
  • Blog
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 DevOpsLesson. All rights reserved.

DOCKERKUBERNETESTERRAFORMAWSCI/CDLINUXGITDEVOPS ROADMAPCLOUD ROADMAPSRE ROADMAPGIT CHEATSHEETDOCKER CHEATSHEETK8S CHEATSHEETTF CHEATSHEETLINUX CHEATSHEETDOCKERFILE LINTERYAML VALIDATORCRON PARSERREGEX TESTER

Docker Tutorial

Introduction to docker
Why Use Docker?
Docker vs Virtual Machines
Installing Docker
Key Docker Concepts
Docker Images
Docker Containers
Writing Dockerfiles
Docker Volumes

Volumes & Storage

PreviousPrev
Next

Persist data beyond container lifecycles with named volumes and bind mounts. Understand when to use each and how to manage them.

Why Container Storage Is Temporary

Each container has its own isolated filesystem layer. It's writable while the container runs, but it's tied to that container's lifecycle. Remove the container, lose the data. For anything that needs to outlive a container like database data, user uploads, logs; you need to store it outside the container using one of Docker's three storage options:

TypeManaged ByBest For
Named VolumeDockerDatabases, persistent app data
Bind MountYouLocal development, config files
tmpfs MountMemory (not disk)Sensitive temp data

Named Volumes

Named volumes are stored in Docker's own managed area on your host (/var/lib/docker/volumes/ on Linux). You don't need to know the exact path, Docker manages it for you.

# Create a volume explicitly
docker volume create mydata

# Or let Docker create it automatically on first use
docker run -d \
  --name postgres \
  -v pgdata:/var/lib/postgresql/data \
  postgres:16

The -v syntax is volume-name:path-inside-container. Docker creates the volume if it doesn't exist yet.

The key benefit is that data survives container removal:

# Start a database container
docker run -d --name db -v pgdata:/var/lib/postgresql/data postgres:16
# ... add data to the database ...

# Remove the container
docker rm -f db

# Recreate it with the same volume and you'll see that all data is still there
docker run -d --name db -v pgdata:/var/lib/postgresql/data postgres:16

The container is gone but the volume isn't. Named volumes only get deleted when you explicitly remove them.

Bind Mounts

A bind mount maps a specific folder or file from your host machine directly into the container. Changes on either side are reflected instantly which means no rebuild, no restart. Edit a file in your editor, and the container sees it immediately. This is the standard way to run a development server in Docker without rebuilding the image on every change.

# Mount your current project directory into the container
docker run -d \
  --name my-app \
  -v $(pwd):/app \
  -p 3000:3000 \
  node:20-alpine \
  sh -c "cd /app && npm run dev"

# Mount a directory to capture logs on the host
docker run -d \
  -v $(pwd)/logs:/app/logs \
  my-app

Named Volume vs Bind Mount

ScenarioUse
Database dataNamed volume
Local development with live reloadBind mount
Config files you want to edit easilyBind mount
Production persistent dataNamed volume
CI/CD artifacts you need on the hostBind mount
Portability across different machinesNamed volume

The short version: named volumes for data that needs to last, bind mounts for files you're actively working with.

tmpfs Mounts

It is a In-Memory Storage and can be used for sensitive data (tokens, secrets, session data) that should never be written to disk. A tmpfs mount exists only in memory. It's fast, it's never written to disk, and it disappears completely when the container stops. It is perfect for temporary files or sensitive in-memory data.

docker run -d \
  --tmpfs /app/tmp:rw,size=64m \
  my-app

Managing Volumes

# List all volumes
docker volume ls

# Inspect a volume (find its actual location on the host)
docker volume inspect pgdata

# Remove a specific volume
docker volume rm mydata

# Remove all volumes not attached to any container
docker volume prune

# Remove without being prompted to confirm
docker volume prune -f

Sharing a Volume Between Containers

Multiple containers can mount the same volume at the same time:

# Create a shared volume
docker volume create shared-logs

# App container writes logs to it
docker run -d --name app -v shared-logs:/app/logs myapp

# Log shipper reads from it (read-only)
docker run -d --name logshipper -v shared-logs:/logs:ro fluentd

One writer, multiple readers is safe. Multiple containers writing to the same files simultaneously can corrupt data, so design it carefully.

Backing Up and Restoring Volumes

Since named volumes are managed by Docker, backing them up means spinning up a temporary container to read and archive the data:

# Back up a volume to a tar file on your host
docker run --rm \
  -v pgdata:/source:ro \
  -v $(pwd):/backup \
  alpine tar czf /backup/pgdata-backup.tar.gz -C /source .

# Restore from that backup into a volume
docker run --rm \
  -v pgdata:/target \
  -v $(pwd):/backup \
  alpine tar xzf /backup/pgdata-backup.tar.gz -C /target

This pattern is using a lightweight Alpine container to read or write volume contents and is the standard Docker approach for volume backups.

Quick Reference

CommandWhat It Does
docker volume create <n>Create a named volume
docker volume lsList all volumes
docker volume inspect <n>See volume details and host path
docker volume rm <n>Delete a specific volume
docker volume pruneDelete all unused volumes
-v name:/pathMount a named volume
-v $(pwd):/pathMount current directory (bind mount)
-v /host/file:/container/file:roRead-only bind mount

Key Takeaways

  • Container filesystems are temporary which means data written inside a container is lost when the container is removed unless you use a volume or bind mount
  • Named volumes are Docker-managed and survive container removal. They're the right choice for databases and any data that needs to last
  • Bind mounts map host paths directly into the container ideal for local development where you want live code reload without rebuilding
  • Deleting a container does not delete its volumes. You have to explicitly run docker volume rm or docker volume prune to free up the space
  • tmpfs mounts store data in memory only, never on disk, use them for secrets or sensitive temp files
  • Run docker volume prune periodically to clean up volumes left behind by removed containers

Frequently Asked Questions

If I delete a container, does its volume get deleted too?

No. Named volumes persist independently of containers. The volume and its data stick around until you explicitly remove it with docker volume rm or docker volume prune. This is a common source of confusion for beginners, and also why docker volume prune is a useful cleanup command.

What's the difference between a named volume and a bind mount?

A named volume is managed by Docker and you can use it by name and Docker handles where it lives on your host. A bind mount is a specific path on your host machine that you map into the container. Named volumes are more portable and better for persistent data; bind mounts are more convenient for development because you can see and edit the files directly.

Why is my bind mount showing an empty directory inside the container?

If the container image already has files at the mounted path, the bind mount will hide them. Either pre-populate your host directory with the needed files, or use a named volume which merges with the image's existing content at that path.

Can two containers write to the same volume at the same time?

They can, but it's risky. Concurrent writes to the same files from multiple containers can corrupt data as there's no built-in locking. The safe pattern is one writer and multiple read-only readers (using :ro).

How do I find where a named volume is stored on my host?

Run docker volume inspect <name> and look at the Mountpoint field. On Linux it's usually under /var/lib/docker/volumes/. On Mac and Windows, volumes live inside the Docker Desktop VM, so you can't browse them directly from Finder/Explorer, that's why named volumes are better than bind mounts for those platforms.

What happens to my data if I run docker volume prune?

It permanently deletes all volumes that aren't currently attached to at least one container (running or stopped). Before running it, check docker volume ls and make sure you're not about to lose anything important. There's no undo.

PreviousPrev
Next

Continue Learning

Exec & Interact

Shell into running containers, execute one-off commands, copy files, and debug live services with docker exec and docker cp.

8 min·Easy

Logs & Monitoring

Stream, filter, and manage container logs. Monitor resource usage with docker stats. Know what your containers are doing in real time.

7 min·Easy

Networking Basics

Understand Docker's networking model including bridge networks, port publishing, container DNS, and how containers communicate with each other.

10 min·Easy

Explore Related Topics

Ku

Kubernetes Tutorials

Orchestrate your Docker containers at scale

CI

CI/CD Tutorials

Automate Docker builds and deployments in pipelines

Try the Tool

Dockerfile Linter

Instantly lint your Dockerfile for best-practice violations and security issues.

On This Page

Why Container Storage Is TemporaryNamed VolumesBind MountsNamed Volume vs Bind Mounttmpfs MountsManaging VolumesSharing a Volume Between ContainersBacking Up and Restoring VolumesQuick ReferenceKey TakeawaysFrequently Asked Questions