For a long time I had this problem that I did not know how to solve:
When you run Docker on a linux host, mount an external folder, all the files created in the docker will be owned by user root
on the host file-system.
Finally I think I understood how this works and found a solution. At least a partial solution.
The Problem
Here is the problem again:
I run docker and mount the current folder as /opt inside the container:
$ docker run -it --rm -w /opt -v$(pwd):/opt ubuntu:23.04 bash
When inside the container I create a file and then exit the container:
# touch hello
# exit
If I look at the ownership of the file on my host computer (which is also Ubuntu):
$ ls -l hello
I get:
-rw-r--r-- 1 root root 0 Apr 26 20:35 hello
The file is now owned by user root
.
Solution
Add the --user ubuntu
parameter to the command:
$ docker run -it --rm -w /opt -v$(pwd):/opt --user ubuntu ubuntu:23.04 bash
Inside the container create a file and exit:
$ touch world
$ exit
Outside, on the host, check the ownership:
$ ls -l world
-rw-r--r-- 1 gabor gabor 0 Apr 26 20:38 world
It is now owned by gabor
which is my regular user.
Explanation
In Linux each user has a user id. The user root
has the id 0 on every Linux machine and I guess also on macOS, but I have not checked it.
So both on my host computer and inside the Docker container the user root
has the same id.
When I ran docker in the first example (without passing the --user
parameter), inside the container I became user root
.
Any file I created then got the userID 0 as its owner. This is also the user root
outside, so that's why the file is owned by
root on the host system.
The first real user on Ubuntu (and I think in general on every Linux and Unix system) will get the id 1000. So the user ID of my
user "gabor" on my host computer has the ID 1000. I could verify this by running the id
command on my computer.
The Docker image 23.04 also comes with a default real user account which is called ubuntu
and it also has the ID 1000.
When in the 2nd example I used the --user ubuntu
flag I entered the container as user ubuntu
. If I ran the id
command there
I'd see:
$ id
uid=1000(ubuntu) gid=1000(ubuntu) groups=1000(ubuntu),4(adm),20(dialout),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev)
showing that this user in the container also has the ID 1000.
I found out about this by listing all the users using the cat /etc/passwd
command. It is the last row.
So when I created a file on the mounted volume the file was created as user ubuntu (id 1000) inside the container.
However on my host machine that id belongs to my regular user, so my computer sees that file as own by user gabor (id 1000).
Just as if I created it as my regular user on the host computer.
This solves the problem.
Notes and warnings
If on the host system your ID is not 1000, then this will not work, but you can create a user in the container with the ID you have
and use that username.
Now that inside the container I am user ubuntu
I don't have the privileges of user root
so I cannot make changes
to any of the system files. In particular I cannot install any extra software using apt
.
I have not tried any other images. I am quite sure that the default user in a CentOS-based image won't be called "ubuntu", if it has one.
CentOS
After a little pause I though I'll try CentOS as well.
I ran
$ docker run -it --rm -w /opt -v$(pwd):/opt centos:7 bash
and then inside the container
# cat /etc/passwd
This showed that all the user IDs are below 1000, they are all system-related users. So I need to create a user.
I created a Dockerfile with the following content:
FROM centos:7
RUN useradd centos
That RUN command will create a user with the username centos
:
Built my own images:
$ docker build -t mycentos .
Ran docker using that images:
$ docker run -it --rm -w /opt -v$(pwd):/opt --user centos mycentos bash
Inside the containe I first checked the id then created a file, then exited:
$ id
$ cat /etc/passwd
$ exit
Outside I checked:
$ ls -l cent
-rw-rw-r-- 1 gabor gabor 0 Apr 26 22:26 cent
It looks fine.
Conclusion
On Ubuntu there is already a user called ubuntu
, on CentOS there is no user, but we can create one easily.
I assume on any other image you would either already had a user or you could create one.