Chapter 20Lesson 02~150 minutes

Volumes, Named Volumes, Volume Drivers, Backup/Restore, Sharing, and Persistent Data Patterns: Guided Hands-On Workflow and Core Operations

Create, inspect, share, back up, restore, verify, and remove disposable named volumes while proving that container replacement does not equal data replacement.

Hands-onBackupRestoreChecksumsExact cleanup

Learning objectives

  • Create and inspect a labeled named volume with the local driver and record its exact metadata.
  • Prove data survives replacement of the container that originally wrote it.
  • Use sequential helper containers to share the same data without assuming concurrent-write safety.
  • Create a tar backup plus SHA-256 checksum, restore it into a different named volume, and verify content and metadata.
  • Remove only exact disposable resources after proving no remaining lab dependency exists.
Lab safety. Everything uses synthetic text data, BusyBox, named volumes prefixed da20-, and a local ./da20-backup directory. No database, secret, production path, plugin, daemon mutation, or broad prune operation is required.

1. Preflight, workspace, and evidence

Create a dedicated workspace and record the active engine/context before creating storage. The volume label provides an ownership guard for later inventory.

docker version
docker info
docker context show
docker compose version || true
docker buildx version || true

docker volume ls
docker ps -a --no-trunc

docker pull busybox:1.36.1
docker image inspect busybox:1.36.1 --format 'ID={{.Id}} RepoDigests={{json .RepoDigests}}'
mkdir -p da20-lab/da20-backup da20-lab/evidence
cd da20-lab

docker volume ls --filter label=devops-academy.lab=ch20

docker ps -a --filter label=devops-academy.lab=ch20

2. Create and inspect the named volume

The local driver is selected explicitly even though it is the default. The label does not affect data; it expresses lab ownership.

docker volume create   --driver local   --label devops-academy.lab=ch20   --label devops-academy.purpose=primary-data   da20-data

docker volume inspect da20-data | tee evidence/volume-before.json

docker volume inspect da20-data \
  --format   'Name={{.Name}} Driver={{.Driver}} Scope={{.Scope}} Mountpoint={{.Mountpoint}} Options={{json .Options}} Labels={{json .Labels}}'

On Docker Desktop, the mountpoint shown by the daemon belongs to Docker's managed Linux environment, not necessarily to a path you should browse from the desktop host. Treat it as evidence, not as the supported data-management interface.

3. Write synthetic state through a container mount

Use long --mount syntax so source and target are unambiguous. Record both a logical version marker and a data file.

docker run --rm   --name da20-writer   --label devops-academy.lab=ch20   --mount type=volume,src=da20-data,dst=/data   busybox:1.36.1 sh -c '
    set -eu
    printf "version=1\n" > /data/VERSION
    printf "alpha\nbeta\ngamma\n" > /data/records.txt
    sha256sum /data/VERSION /data/records.txt
    ls -ln /data
  ' | tee evidence/write.txt

docker volume inspect da20-data > evidence/volume-after-write.json

The writer container is gone because of --rm; the volume remains. That is the lifecycle separation the chapter is teaching.

4. Replace the container, not the data

A new reader container mounts the same volume. It has a different container ID but observes the same persisted files.

docker run --rm   --name da20-reader   --label devops-academy.lab=ch20   --mount type=volume,src=da20-data,dst=/data,readonly   busybox:1.36.1 sh -c '
    cat /data/VERSION
    cat /data/records.txt
    sha256sum /data/VERSION /data/records.txt
    ls -ln /data
  ' | tee evidence/read-after-replacement.txt

The read-only mount proves the second container needs no write permission for verification. Sequential sharing says nothing about whether the application would tolerate multiple concurrent writers.

5. Create a checksum-backed backup artifact

Because no writer is running, this file-level backup is consistent for the synthetic dataset. The helper mounts the source read-only and the host backup directory read-write.

docker run --rm   --name da20-backup-helper   --label devops-academy.lab=ch20   --mount type=volume,src=da20-data,dst=/source,readonly   --mount type=bind,src="$(pwd)/da20-backup",dst=/backup   busybox:1.36.1 sh -c '
    set -eu
    cd /source
    tar -czf /backup/da20-data-v1.tgz .
    sha256sum /backup/da20-data-v1.tgz > /backup/da20-data-v1.tgz.sha256
  '

cat da20-backup/da20-data-v1.tgz.sha256
sha256sum -c da20-backup/da20-data-v1.tgz.sha256

If your shell/host uses different bind-path syntax, adapt only the source path and record the platform-specific substitution. The backup filename and checksum remain the evidence contract.

6. Restore into a new volume

Never overwrite the original first when testing recovery. Create a fresh target, extract the archive there, then compare logical content and file checksums.

docker volume create   --driver local   --label devops-academy.lab=ch20   --label devops-academy.purpose=restore-target   da20-restore

docker run --rm   --name da20-restore-helper   --label devops-academy.lab=ch20   --mount type=volume,src=da20-restore,dst=/restore   --mount type=bind,src="$(pwd)/da20-backup",dst=/backup,readonly   busybox:1.36.1 sh -c '
    set -eu
    cd /restore
    tar -xzf /backup/da20-data-v1.tgz
    cat VERSION
    cat records.txt
    sha256sum VERSION records.txt
    ls -ln .
  ' | tee evidence/restore.txt

7. Compare source and restored content independently

docker run \
  --rm \
  --mount type=volume,src=da20-data,dst=/data,readonly   busybox:1.36.1 sh -c 'cd /data; sha256sum VERSION records.txt'   | sort > evidence/source-files.sha256

docker run \
  --rm \
  --mount type=volume,src=da20-restore,dst=/data,readonly   busybox:1.36.1 sh -c 'cd /data; sha256sum VERSION records.txt'   | sort > evidence/restored-files.sha256

diff -u evidence/source-files.sha256 evidence/restored-files.sha256

An empty diff verifies byte equality for these files. It does not prove a database would be transactionally consistent; consistency must be defined by the application.

8. Prove no container dependency before deletion

docker ps -a --filter volume=da20-data --no-trunc
docker ps -a --filter volume=da20-restore --no-trunc

docker volume inspect da20-data da20-restore > evidence/volumes-final.json

If either query lists an unexpected container, stop and investigate ownership. Do not force deletion to make cleanup succeed.

9. Exact cleanup

docker volume rm da20-data da20-restore

docker volume ls --filter label=devops-academy.lab=ch20

# Keep ./da20-backup and ./evidence until you have reviewed the recovery evidence.
# No broad volume/system prune is part of this lab.

10. Challenge: choose the right layer

A replacement container starts successfully but reports “permission denied” on the restored volume. Which layer should you inspect first: registry, network, container image identity, or storage ownership? Capture the restored files' numeric UID/GID and the replacement process UID/GID before changing anything. The likely first mismatch is storage authorization, not networking.

Next lesson

Next: Volumes, Named Volumes, Volume Drivers, Backup/Restore, Sharing, and Persistent Data Patterns: Configuration, Design Choices, and Tradeoffs

Compare named volumes with bind mounts and external drivers, define safe sharing/backup semantics, and decide who owns volume creation and deletion in Compose.

Knowledge check

Why does the backup helper mount the source volume read-only?

Why restore into da20-restore instead of overwriting da20-data?

Does an empty file checksum diff prove database consistency?

Why query containers by volume before removal?

What state changed when the first writer container exited?

Official references and version notes

Version baseline, verified 2026-09-21.

Docker Engine 29.8.1 is current; Docker Compose 5.5.1, Buildx 0.37.1, and BuildKit 0.33.0 are the current upstream baselines used for compatibility discussion. The mandatory labs use the built-in local volume driver and BusyBox, require no paid service, and record the learner's actual installed versions rather than assuming they match upstream.

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this address.