Docker Bind Mount "Permission denied" Under SELinux - Use the :z/:Z Label
On an SELinux-enforcing host (RHEL/CentOS/Fedora runners), a bind-mounted host directory is denied to the container because its SELinux label does not permit container access. The :z/:Z mount option relabels it.
What this error means
A container with a bind mount gets Permission denied reading or writing the mounted path, even though file ownership/permissions look correct. dmesg/ausearch shows an SELinux avc: denied for the container context.
# inside the container, on an SELinux host:
cat: /data/config.yml: Permission denied
# audit log: avc: denied { read } for ... scontext=...:container_t tcontext=...:default_tCommon causes
Host path lacks a container-accessible SELinux label
SELinux confines containers to the container_t domain. A host directory labeled for general use is not accessible from inside the container unless relabeled for container access.
Mount missing the :z or :Z suffix
Docker only relabels a bind mount when you add :z (shared) or :Z (private) to the volume spec. Without it, SELinux blocks access.
How to fix it
Add the :z or :Z relabel option
Append the SELinux label option so Docker relabels the mounted content for container access.
# shared content (multiple containers may use it): lowercase z
docker run -v "$PWD/data:/data:z" myorg/api
# private to one container: uppercase Z
docker run -v "$PWD/data:/data:Z" myorg/apiSet the label in compose
Compose supports the same suffix in the volume short syntax.
services:
api:
volumes:
- ./data:/data:zHow to prevent it
- Add
:z/:Zto bind mounts on SELinux-enforcing runners. - Scope
:Zto the exact directory the container needs, not a broad parent. - Document the SELinux requirement next to compose/run configs for RHEL-family runners.