Ownership Inheritance for Docker Generated Files

Introduction

When we use Docker containers, usually it is necessary to give the root privilege to Docker. This means that the files generated in the Docker container would belong to the root user and ordinary users do not own those files. This is sometimes problematic if we want to get access to or manipulate those files outside the container.

In this blog post, I would like to show how to generate files in Docker container that belongs to the current user instead of the root user.

Experiments

Owned By Root User

We would use the ubuntu:20.04 image to run our container.

1
$ docker run -it --rm -v $(pwd):/mnt ubuntu:20.04

In the container, we found that we are the root user. We created an dummy.txt and exited the container.

1
2
3
root@d4ed0d87eb41:/# cd /mnt/
root@d4ed0d87eb41:/mnt# touch dummy.txt
root@d4ed0d87eb41:/mnt# exit

On the host system, we found that this file is owned by the root user. Only the root user has the write privilege.

1
2
$ ls -lh dummy.txt 
-rw-r--r-- 1 root root 0 Apr 17 14:28 dummy.txt

Owned By Current Host User

If we add a magic argument -u $(id -u):$(id -g) for starting the Docker container.

1
$ docker run -it --rm -u $(id -u):$(id -g) -v $(pwd):/mnt ubuntu:20.04

In the container, we found that we are the user I have no name!. This looks weird but we ignored it for now. We created an dummy.txt anyway and exited the container.

1
2
3
4
5
6
$ docker run -it --rm -u $(id -u):$(id -g) -v $(pwd):/mnt ubuntu:20.04
groups: cannot find name for group ID 1000
I have no name!@1b1e4cb8430c:/$ cd /mnt/
I have no name!@1b1e4cb8430c:/mnt$ ls
I have no name!@1b1e4cb8430c:/mnt$ touch dummy.txt
I have no name!@1b1e4cb8430c:/mnt$ exit

On the host system, we found that this time this file is owned by leimao which is the current user on the host. We are the owner of the file and we do have the write privilege.

1
2
$ ls -lh dummy.txt 
-rw-r--r-- 1 leimao leimao 0 Apr 17 14:37 dummy.txt

Mechanisms

Let’s see the mechanism of this.

On the host system, we could find our user id uid and group id gid using (id -u) and (id -g) respectively.

1
2
3
4
5
6
$ id
uid=1000(leimao) gid=1000(leimao) groups=...
$ echo $(id -u)
1000
$ echo $(id -g)
1000

According to docker run --help, we actually specified the uid and gid for the user in the Docker container.

1
2
3
4
$ docker run --help
...
-u, --user string Username or UID (format: <name|uid>[:<group|gid>])
...

Therefore, the file generated in the container would have the exact uid and gid that the current host user are using, and on the host system the current host user would own those files.

We could verify this in the Docker container.

1
2
3
$ docker run -it --rm -v $(pwd):/mnt ubuntu:20.04
root@f188141b3870:/# id
uid=0(root) gid=0(root) groups=0(root)
1
2
3
4
$ docker run -it --rm -u $(id -u):$(id -g) -v $(pwd):/mnt ubuntu:20.04
groups: cannot find name for group ID 1000
I have no name!@5efc24041d43:/$ id
uid=1000 gid=1000 groups=1000

Conclusions

-u $(id -u):$(id -g) is no longer a magic. Use it when it is necessary.

Author

Lei Mao

Posted on

04-17-2020

Updated on

04-17-2020

Licensed under


Comments