Docker Mounting
- All data written inside a container’s writable layer is ephemeral - it disappears when the container is removed.
- To persist data or share it between containers and the host, you attach external storage via a mount.
- Three main mount types: Volumes (Docker-managed), Bind Mounts (host path), tmpfs (memory-only).
Mount Types Comparison
Section titled “Mount Types Comparison”| Type | Managed by | Persists after docker rm | Performance | Best For |
|---|---|---|---|---|
| Volume | Docker | Yes | Native | Production data, database storage |
| Bind Mount | Host OS | Yes (host file) | Native | Development, config injection |
| tmpfs | Kernel (memory) | No | Fastest | Secrets at runtime, temp caches |
Volumes
Section titled “Volumes”- Volumes are the recommended way to persist data in production. Docker creates a directory on the host (typically
/var/lib/docker/volumes/<name>/_data) and manages it independently of the container lifecycle. - Volumes can be shared across multiple containers and survive container removal.
# Create a named volumedocker volume create db-data
# List volumesdocker volume ls
# Inspect a volume (find its host path)docker volume inspect db-data
# Mount a volume at container run timedocker run -d \ -v db-data:/var/lib/postgresql/data \ # named volume syntax postgres:16-alpine
# Same with --mount (more explicit, preferred in scripts)docker run -d \ --mount type=volume,src=db-data,dst=/var/lib/postgresql/data \ postgres:16-alpine
# Read-only volumedocker run -d \ --mount type=volume,src=config-vol,dst=/etc/app,ro \ my-app
# Remove a volume (only when no containers use it)docker volume rm db-data
# Remove all unused volumesdocker volume prune[!important]
docker compose downdoes NOT remove named volumes. Usedocker compose down -vto also remove volumes. This is intentional - protecting production data from accidentaldowncommands.
Where Volume Data Lives
Section titled “Where Volume Data Lives”On Linux: /var/lib/docker/volumes/<volume-name>/_data
On Docker Desktop (macOS/Windows), Docker runs inside a Linux VM. Volume data is inside that VM’s filesystem - not directly accessible from your Mac/Windows filesystem. To inspect it:
# Access the Docker Desktop VM filesystem (use this exact pinned image - security)docker run -it --rm --privileged --pid=host \ justincormack/nsenter1@sha256:5af0be5e42ebd55eea2c593e4622f810065c3f45bb805eaacf43f08f3d06ffd8
# Then navigate to the volume data inside the VMls /var/lib/docker/volumes/db-data/_dataBind Mounts
Section titled “Bind Mounts”- Maps a specific host path directly into the container. Changes are immediately visible on both sides.
- Ideal for development (mount source code into a container so edits are reflected live) or injecting configuration files.
- Not portable - depends on a specific host path existing. Avoid in production images.
# Bind mount the current directory to /app in the containerdocker run -d \ -v $(pwd):/app \ # short syntax -v $(pwd)/nginx.conf:/etc/nginx/nginx.conf:ro \ # read-only my-app
# --mount equivalent (clearer for CI/CD scripts)docker run -d \ --mount type=bind,src=$(pwd),dst=/app \ my-app[!caution] Changes in a bind mount are immediate and bidirectional. Deleting files in the container deletes them on the host. Be careful in development with bind mounts on directories containing important data.
tmpfs Mounts
Section titled “tmpfs Mounts”- Data stored in memory only - never written to disk. Lost when the container stops or restarts.
- Use for sensitive data (tokens, API keys at runtime) that must not be persisted to disk, or for high-speed temporary caches.
# Mount a tmpfs at /tmp/cache in the containerdocker run -d \ --mount type=tmpfs,dst=/tmp/cache \ my-app
# With size and mode options# tmpfs-mode=1700 = octal 0o1700 = sticky bit + rwx for owner only (no group/other access)docker run -d \ --mount type=tmpfs,dst=/tmp/secrets,tmpfs-size=64m,tmpfs-mode=1700 \ my-app[!important] If the host runs out of memory, the kernel may swap tmpfs to disk, defeating the purpose. Monitor memory usage if relying on tmpfs for secret isolation.
Configs and Secrets (Swarm Mode Only)
Section titled “Configs and Secrets (Swarm Mode Only)”- Secrets and Configs are Docker Swarm primitives for distributing sensitive data to services without embedding it in images or environment variables.
- Only available in Swarm mode - not in standalone
docker runor Compose without Swarm.
# Create a secret from a fileecho "supersecretpassword" | docker secret create db_password -
# Use in a Swarm servicedocker service create \ --name my-app \ --secret db_password \ my-app-image# Secret is mounted at: /run/secrets/db_password- In Compose with Swarm, use the
secrets:key. For non-Swarm Compose, use environment variables from.envfiles or bind-mount config files instead.
Volume Drivers
Section titled “Volume Drivers”By default, volumes are stored on the local host filesystem. Volume drivers let you back a named volume with remote or distributed storage:
# Example: NFS-backed volume (useful with AWS EFS on EC2)docker volume create \ --driver local \ --opt type=nfs \ --opt o=addr=efs.example.com,rw \ --opt device=:/ \ efs-dataCloud-native alternatives: AWS EFS CSI driver (EKS), Azure Files (AKS), GCS Fuse — these are typically configured at the orchestrator level, not directly with Docker.
Choosing the Right Mount
Section titled “Choosing the Right Mount”- Databases and stateful services in production → Named Volume
- Source code in development → Bind Mount (live reload)
- Config files → Bind Mount (read-only) or Docker Secret (Swarm)
- Build artifacts or temp files → tmpfs or anonymous volume
- Sharing data between containers → Named Volume
- Cross-host persistence (multi-node) → Volume with NFS/cloud driver or orchestrator CSI