While Docker is quite handy in many ways, one inconvenient aspect is that if one mounts some host machine directory inside Docker, and the Docker image does something to those files as a non-root user, one will run into problems if the UID of the host machine user and the Docker image user do not match.
Consider this scenario: I my user ‘otto’ is running on the host machine as UID 1001. Then I spin up a development image with Docker where I do development and store files in a locally mounted directory. Inside there is a temporary Docker user called ‘vagrant’ with the UID 1000. Now whenever any files are updated (say via composer update for example) it will fail to work, as the mounted directory is owned by UID 1001 and the Docker image user with UID 1000 will not be able to write anything.
Docker run –user does not help
If one has complete control of the Docker image, one could modify the UID of the Docker user and rebuild. Most of the time that is however not an option. Docker run has the option --user
but that does not help if the Docker image already has created the user with a particular name and UID/GID settings.
Subuser and subgroup mapping to the rescue
To use subuser and subgroup mapping, first enable the feature in Docker by editing the /etc/docker/daemon.json config file to include:
{
"userns-remap": "otto"
}
Naturally, replace ‘otto’ with your own username. For changes to take effect, restart Docker with sudo systemctl restart docker
and check with sudo systemctl status docker
that is restarted wihtout failures and is running.
To instruct the mapping, edit the files /etc/subuid
(for user IDs) and /etc/subgid
(for group IDs). In the case above, I mapped users 0-1000 to have the same UID/GID both inside and outside Docker. I want for root to have UID 0 all the time. However the user IDs should start from 1001 and not from 1000. This way the most common UID inside the Docker container 1000 will match my own laptop UID 1001 of my user.
otto:0:1000
otto:1001:65536
Voila!
Read more
Original idea by https://ilya-bystrov.github.io/posts/docker-daemon-remapping/
Details at http://man7.org/linux/man-pages/man5/subuid.5.html and https://echorand.me/posts/docker-user-namespacing-remap-system-user/
Hi Otto, can I ask to explain a bit more how to map UIDs using /etc/subuid and /etc/subgid files?
In my case, I have user jira with id 500 on the host system and user jira with id 2001 inside docker container.
I would like files modified by jira inside container (2001) to be owned by id 500 on the host side, so jira user on the host could also have access to the data. When I followed your instructions, I ended up with host files owned by ID 2501. So it looks like docker took container user jira id (2001) and added 500 (the ID I want to be the owner on the host side.
What am I doing wrong here? Thanks!!!