# Docker bind-mount UID/GID troubleshooting checklist Use this before changing permissions. Replace placeholders; do not paste production paths into commands blindly. ## 1. Capture facts ```bash id stat -c 'path=%n mode=%a uid=%u gid=%g' ./data docker compose config docker compose run --rm app sh -c 'id; stat -c "path=%n mode=%a uid=%u gid=%g" /app/data' docker inspect --format '{{json .Mounts}}' ``` Record: host UID/GID, container UID/GID, numeric owner/mode of every parent directory, mount source/target, `RW`, and whether Docker is rootless or uses `userns-remap`. ## 2. Classify the failure - Numeric owner/mode mismatch: container UID/GID cannot write. - `RW: false`: mount is intentionally read-only; ownership changes will not make it writable. - Missing parent execute/search permission: the file may be writable but unreachable. - SELinux denial: inspect labels/audit logs; do not apply `:Z` to broad system directories. - Rootless or `userns-remap`: host IDs may be translated; inspect the mapping before `chown`. - Remote/NFS/SMB filesystem: server/export rules may override local mode bits. ## 3. Choose the narrowest remediation Preferred for a development bind mount: ```yaml services: app: user: "${HOST_UID}:${HOST_GID}" volumes: - type: bind source: ./data target: /app/data bind: create_host_path: false ``` Launch with explicit values (Compose interpolation does not execute shell commands): ```bash HOST_UID="$(id -u)" HOST_GID="$(id -g)" docker compose up ``` If the application must use a fixed service UID/GID, change ownership only on its dedicated data directory after backing up and confirming the numeric IDs: ```bash sudo chown --from=: -R : ./data ``` Alternatives: grant a dedicated shared group and minimal group-write permission, use a Docker-managed named volume for service data, or copy immutable configuration with a read-only mount. Avoid: `chmod -R 777`, running the application as root as a permanent fix, recursive `chown` on `/`, `/home`, or an unverified path, and changing SELinux labels broadly. ## 4. Verify and roll back ```bash docker compose run --rm app sh -c 'id; touch /app/data/.permission-test; stat -c "%a %u %g %n" /app/data/.permission-test; rm /app/data/.permission-test' ``` Confirm the host sees the expected numeric owner and that the application still starts. Roll back the Compose change or restore the recorded owner/group from backup if the service regresses. Last lab retest: 2026-08-30. Refresh after Docker Engine, image, host security mode, or storage backend changes.