Relentless Coding

A Developer’s Blog

Docker Volume Permissions: Mismatch Between Host UID and Container UID

When you have a Docker container with a user that has a different UID from the one on your host, mounting a volume and accessing the files can result in permission issues.

Let’s say the UID of the Docker user is 12345. The files on the host are owned by UID 1000. This means the permissions do not hash and the container user cannot access the files.

One solution is to use ACLs to grant the container user access.

Prerequisites

After reading the Arch Linux wiki, check if you filesystem supports ACLs:

# tune2fs -l /dev/sdXY | grep "Default mount options:"
Default mount options:    user_xattr acl

New Files Inherit Group

$ find ./somedir -type d -execdir chmod g+s {} \+

First, we set the SGID bit on all directories in the volume. Now, newly created files inherit the group ownership of the directory. When the user 12345 creates a new file or directory inside the Docker container, the host user 1000 will still be able to access those files.

Set Inherited Default ACL on Directories

$ find ./somedir -type d -execdir setfacl -dm u:12345:rwX {} \+

Next, we set default ACLs on all directories in the volume. Newly created files will inherit this default ACL. If the default ACL has user:12345:rwx specified and we create a new file with touch, which uses a mode of 00666, the resulting file will have an ACL of user:12345:rw-. This is because no permissions can be present that are not specified in the mode parameter of the open system call. acl(5) explains this in more detail.

Set ACL on All Files and Directories

$ find ./somedir -execdir setfacl -m u:12345:rwX {} \+

Finally, we set rw permissions on all files and directories. The X is handy, it sets

execute/search only if the file is a directory or already has execute permission for some user

So it will only set search permissions on directories, which need it so the Docker user can descend into them, or on files that are already executable.

See Also

chmod(1), acl(5), getfacl(1) and setfacl(1)