Bind Mounts, Read-Only Mounts, tmpfs, Mount Propagation, Subpaths, SELinux Labels, and Host Coupling: Configuration, Design Choices, and Tradeoffs
Choose deliberately among named volumes, bind mounts, tmpfs, propagation modes, SELinux labels, and development-versus-production host coupling.
Learning objectives
- Choose among named volumes, bind mounts, and tmpfs based on lifecycle, portability, authority, and performance requirements.
- Decide when a bind should be read-only and when host write access is truly required.
- Explain why development-friendly host coupling can be a production portability and security liability.
-
Choose private/shared propagation and SELinux
z/Zonly when the host/platform requirements justify them. - Use normalized Compose configuration to expose path-creation and mount-policy assumptions before execution.
1. Named volume vs bind mount vs tmpfs
| Question | Named volume | Bind mount | tmpfs |
|---|---|---|---|
| Who owns location? | Docker/driver | Daemon host operator | Kernel memory |
| Survives container? | Yes, until removed | Host path survives independently | No |
| Portable across hosts? | More portable at app level; driver still matters | Low; path/layout must exist | High at config level, Linux/runtime support required |
| Host write exposure? | Through driver-managed storage | Direct if writable | No host filesystem source |
| Typical use | Persistent app data | Source/config/dev fixtures | Ephemeral runtime scratch |
Do not choose a mount because it is familiar. Start from lifecycle and authority: what must persist, what must be host-visible, and what should vanish?
2. Read-only by default, writable by exception
If a container only needs configuration, templates, certificates, or source inputs, a read-only bind communicates and enforces that contract. Writable binds are appropriate when the container intentionally edits host-visible artifacts, such as a local formatter or code generator. Scope them to the smallest directory possible.
3. Development coupling versus production portability
Bind mounts are excellent for the inner loop because edits made in
the editor are immediately visible to the container. Production
systems are less tolerant of hidden host assumptions. A deployment
that requires /home/alice/project/config to exist on
every host is not self-contained. Prefer images, configs/secrets
mechanisms, or managed storage where practical.
4. Propagation is not a generic “make mounts work” switch
| Mode | Direction | Use posture |
|---|---|---|
rprivate |
No nested mount propagation either direction | Default and safest for most workloads |
rslave |
Host-origin nested mounts may flow into replica, not back | Specialized consumers of host mount changes |
rshared |
Nested mount events can propagate both directions | Rare; requires deliberate Linux host setup and larger trust boundary |
Propagation is supported only on Linux host machines and does not work with Docker Desktop. If you cannot state the nested-mount requirement precisely, keep the default.
5. SELinux: shared label versus private label
z tells Docker the content may be shared among
containers; Z assigns a private container-oriented
label. Both can relabel host files. This is a security-sensitive
host mutation, so use it only on the exact intended application
directory. Never apply Z to broad operating-system
trees.
6. Compose can hide source-creation semantics unless you inspect the model
Compose long syntax exposes bind options including
propagation, create_host_path, and SELinux
labeling. Current Compose documentation states
create_host_path defaults to true. If silent creation
is not acceptable, set it explicitly to false where supported and
inspect docker compose config before up.
services:
app:
image: busybox:1.36.1
command: ["sleep", "300"]
volumes:
- type: bind
source: ./config
target: /app/config
read_only: true
bind:
create_host_path: false
- type: tmpfs
target: /run/app
tmpfs:
size: 1048576
mode: 1770
7. Worked decision table
| Scenario | Choice | Prerequisites | Evidence |
|---|---|---|---|
| Local source editing | Read-write bind of project subtree | Local/Desktop context; shared path on Desktop | Inspect source/target/RW; verify host edit round-trip |
| Read-only runtime config in local lab | Read-only bind | Known host path and appropriate labels | RW=false; failed write test |
| Database data | Named volume rather than source bind | Backup/restore plan; driver semantics | Volume inspect + recovery evidence |
| Temporary session scratch | tmpfs | Memory budget; Linux container support | tmpfs mount inspect + disappearance after stop |
| Nested mount consumer | rslave only if justified |
Linux host and shared-subtree setup | Host mount topology + inspect propagation |
8. Keep adjacent state categories separate
Mount configuration does not fix application listening, network reachability, image identity, authentication, or external storage authorization. Likewise, an image rebuild does not change a host bind source. Diagnose the layer that owns the evidence.
Knowledge check
When is a bind mount preferable to a named volume?
When the application intentionally needs a specific existing daemon-host path, such as editable source or selected host configuration.
What is the best default propagation choice for ordinary applications?
rprivate, because it prevents nested mount
propagation and is Docker's default.
Why can a writable source-code bind cause root-owned developer files?
A root process in the container may create files on the host path with its numeric UID/GID semantics; match users or otherwise design ownership intentionally.
What does Compose create_host_path: false protect
against?
Silent creation of a missing bind source, which can mask path mistakes.
Does a smaller bind scope improve least privilege?
Yes. Mounting only the needed subtree reduces both data exposure and possible host modification surface.
Official references and version notes
-
Docker Docs — Bind mounts
— daemon-host paths, read-only mode,
--mountversus-v, recursive mounts, propagation, and SELinux labeling. - Docker Docs — tmpfs mounts — memory-backed lifetime, size/mode options, and cgroup memory accounting.
- Docker CLI — docker container run — mount and read-only-root-filesystem semantics.
-
Compose Specification — service volumes
— bind options,
create_host_path, SELinux labels, tmpfs, and volume subpaths. -
Docker Docs — Volumes
—
volume-subpathas a mount-type-specific subpath feature and contrast with bind mounts. - Docker Desktop — File sharing — host-to-VM sharing boundaries and performance guidance.
- Docker Desktop — Synchronized file shares — optional paid synchronized host-file caching for large repositories.
-
Docker Engine 29 release notes
— current Engine baseline and
bind-create-srcaddition in 29.3.
Docker Engine 29.8.1 and Docker Desktop 4.91.0 are current; Compose 5.5.1, Buildx 0.37.1, and BuildKit 0.33.0 are the upstream baselines used for compatibility discussion. The labs record the learner's actual versions because host kernel, Docker Desktop VM/file-sharing mode, SELinux, and remote-context topology materially affect mount behavior.
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.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this
address.