Docker containers are always run as root user by default. As a result all running processes, shared volumes, folders, files will be owned by root user. It becomes real problem when we need to modify files and folder in shared folders within host OS or docker container.

In order to solve such issue, we need to match host OS and docker container user's UIDs. The root user's UID is always 0. Running docker as root user is also considered as a bad security practice.


Host filesystem


Current user's information.


ubuntu@linux:~$ echo $HOME
/home/ubuntu

ubuntu@linux:~$ pwd
/home/ubuntu

ubuntu@linux:~$ id
uid=1000(ubuntu) gid=1000(ubuntu) groups=1000(ubuntu)

If you don't manually create the shared folder, docker will create it and it will be owned by root user which is what we don't want to be happening.


ubuntu@linux:~$ mkdir data

ubuntu@linux:~$ ls -l
drwxrwxr-x 2 ubuntu ubuntu 4096 Dec 2 13:39 data

Dockerfile


ubuntu@linux:~$ nano Dockerfile

FROM ubuntu:16.04

ENV user inanzzz

RUN useradd -m -d /home/${user} ${user} \
&& chown -R ${user} /home/${user}

USER ${user}

CMD ["/bin/bash"]

What this does is:


  1. Creates a user and group called inanzzz with UID equals to 1000.

  2. Let inanzzz user recursively own home directory /home/inanzzz.

  3. Switch to inanzzz user to run container.

Create image


ubuntu@linux:~$ docker build -t app_img .

Sending build context to Docker daemon 46.59kB
Step 1/5 : FROM ubuntu:16.04
---> dd6f76d9cc90
Step 2/5 : ENV user inanzzz
---> Running in 145029c73c09
---> 31a5bff4cc84
Removing intermediate container 145029c73c09
Step 3/5 : RUN useradd -m -d /home/${user} ${user} && chown -R ${user} /home/${user}
---> Running in c35e2a504b76
---> c21936ff38a8
Removing intermediate container c35e2a504b76
Step 4/5 : USER ${user}
---> Running in d44cd17ef30d
---> e2ed0f96182b
Removing intermediate container d44cd17ef30d
Step 5/5 : CMD /bin/bash
---> Running in 5665ced5f3e5
---> a4632094fab6
Removing intermediate container 5665ced5f3e5
Successfully built a4632094fab6
Successfully tagged app_img:latest

Create container


This links host /home/ubuntu/data folder to container /home/inanzzz/data folder.


ubuntu@linux:~$ docker run -i -t -d -v $(pwd)/data:/home/inanzzz/data --name app_con app_img

Test


Container


Check user details.


ubuntu@linux:~$ docker exec -it app_con id
uid=1000(inanzzz) gid=1000(inanzzz) groups=1000(inanzzz)

As you can see above, host and container users' UIDs match. Names are not important.


Host  : uid=1000(ubuntu)  gid=1000(ubuntu)  groups=1000(ubuntu)
Guest : uid=1000(inanzzz) gid=1000(inanzzz) groups=1000(inanzzz)

Check current shared folder permissions.


ubuntu@linux:~$ docker exec -it app_con ls -l /home
drwxr-xr-x 1 inanzzz inanzzz 4096 Dec 2 13:44 inanzzz

ubuntu@linux:~$ docker exec -it app_con ls -l /home/inanzzz
drwxrwxr-x 2 inanzzz inanzzz 4096 Dec 2 13:39 data

ubuntu@linux:~$ docker exec -it app_con ls -l /home/inanzzz/data

Create test files.


ubuntu@linux:~$ docker exec -it app_con bash
inanzzz@ce0a5fcb9e17:/$

inanzzz@ce0a5fcb9e17:/$ touch ~/data/guest.txt
inanzzz@ce0a5fcb9e17:/$ echo 'Guest' >> ~/data/guest.txt

inanzzz@ce0a5fcb9e17:/$ ls -l ~/data
-rw-r--r-- 1 inanzzz inanzzz 6 Dec 2 13:51 guest.txt

inanzzz@ce0a5fcb9e17:/$ cat ~/data/guest.txt
Guest

Host OS


As you can see below, the files created in docker container are automatically owned by ubuntu since the user UIDs are same.


ubuntu@linux:~$ ls -l data/
-rw-r--r-- 1 ubuntu ubuntu 6 Dec 2 13:51 guest.txt

Create new and modify existing files.


ubuntu@linux:~$ touch data/host.txt
ubuntu@linux:~$ echo 'Host' >> data/host.txt
ubuntu@linux:~$ echo 'Host' >> data/guest.txt

ubuntu@linux:~$ ls -l data/
-rw-r--r-- 1 ubuntu ubuntu 6 Dec 2 13:51 guest.txt
-rw-rw-r-- 1 ubuntu ubuntu 5 Dec 2 13:54 host.txt

ubuntu@linux:~$ cat data/guest.txt
Guest
Host

ubuntu@linux:~$ cat data/host.txt
Host

Container


Check permissions.


inanzzz@ce0a5fcb9e17:/$ ls -l ~/data
-rw-r--r-- 1 inanzzz inanzzz 11 Dec 2 13:55 guest.txt
-rw-rw-r-- 1 inanzzz inanzzz 5 Dec 2 13:54 host.txt

inanzzz@ce0a5fcb9e17:/$ cat ~/data/guest.txt
Guest
Host

inanzzz@ce0a5fcb9e17:/$ cat ~/data/host.txt
Host

inanzzz@ce0a5fcb9e17:/$ echo 'Guest' >> ~/data/host.txt

inanzzz@ce0a5fcb9e17:/$ ls -l ~/data
-rw-r--r-- 1 inanzzz inanzzz 11 Dec 2 13:55 guest.txt
-rw-rw-r-- 1 inanzzz inanzzz 11 Dec 2 13:57 host.txt

inanzzz@ce0a5fcb9e17:/$ cat ~/data/host.txt
Host
Guest