6. Docker storage: volumes, bind mounts, tmpfs
| Type | Syntax | Managed by | Use for |
|---|---|---|---|
| Named volume | -v pgdata:/var/lib/postgresql/data |
Docker (/var/lib/docker/volumes) |
database data, anything that must outlive the container |
| Bind mount | -v $(pwd)/src:/app/src |
you (host path) | dev hot-reload, injecting config files |
| tmpfs | --tmpfs /tmp:size=64m |
memory | scratch space with a read-only root FS, secrets that must not hit disk |
docker volume create pgdata
docker run -d --name db -e POSTGRES_PASSWORD=dev -v pgdata:/var/lib/postgresql/data postgres:17
docker rm -f db # container gone ...
docker run -d --name db -e POSTGRES_PASSWORD=dev -v pgdata:/var/lib/postgresql/data postgres:17
# ... data survives
# backup a volume: tar it from a throwaway container
docker run --rm -v pgdata:/data -v $(pwd):/backup alpine tar czf /backup/pgdata.tgz -C /data .
Gotchas:
- The writable container layer is not for data. It is slow (copy-on-write) and deleted with the container.
- Bind-mount UID mismatch: a container running as uid 65532 can't write to a host dir owned by uid 501. Fix ownership, or use named volumes.
- Never back up a live database by copying its files. Use
pg_dumpor the database's own backup tool; a file copy of a running DB can be corrupt. - On macOS, bind mounts cross the VM boundary and are slower. Use
Compose
develop.watch(§7.3) or synchronized file shares for big trees.