Quick answer

What this guide helps you do

Diagnose Docker bind-mount permission errors by checking the real host path, mount state, container UID and GID, access modes and security boundaries.

Diagnose the boundary

Most failures come from the wrong host path, a missing host drive, a mismatched UID or GID, an inaccessible parent directory, or a read-only mount. Do not start with chmod 777; it grants unnecessary access and hides the cause.

Prove the host filesystem exists

findmnt /srv/data
df -hT /srv/data
stat /srv/data
namei -l /srv/data

If the path should be a separate disk but findmnt shows nothing, stop the affected container. Otherwise it may write into an empty directory on the root filesystem beneath the intended mount point.

Inspect Docker’s real mount

sudo docker compose config
sudo docker inspect YOUR_CONTAINER --format '{{json .Mounts}}'

Check Source, Destination, mount type and whether write access is enabled. A path typo can cause Docker to expose an unexpected empty directory.

Compare numeric identities

sudo docker exec YOUR_CONTAINER id
sudo docker inspect YOUR_CONTAINER --format '{{.Config.User}}'
stat -c 'owner=%U(%u) group=%G(%g) mode=%a path=%n' /srv/data
namei -l /srv/data/media

Linux checks numeric UID and GID values. The process also needs execute permission on every parent directory.

Apply the narrow fix

Use the image’s documented service identity. Change ownership only where that service should own data, or use a controlled shared group or ACL. Do not recursively change a mixed-use media library without understanding every consumer.

Keep read-only data read-only. Give the application a separate writable path for configuration or cache where possible.

Test inside the container

sudo docker exec YOUR_CONTAINER sh -c 'ls -la /path/in/container'
sudo docker exec YOUR_CONTAINER sh -c 'touch /path/in/container/.permission-test && rm /path/in/container/.permission-test'

Perform the write test only where writing is intended. Apply Compose edits with docker compose up -d; a plain restart does not apply changed configuration.

Verification checklist

  • The intended host filesystem is mounted.
  • Source and destination paths are correct.
  • The mount is writable only where intended.
  • Container UID and GID values are known.
  • Parent directories are traversable.
  • A real read or write test succeeds.
  • The setup survives reboot.

Exact image IDs and supported environment variables must come from that image’s documentation.

Next: Docker Volumes vs Bind Mounts. Start with How to Install Docker on Ubuntu Server.

Official reference: Docker bind mounts.