Skip to content

Instantly share code, notes, and snippets.

@heyfluke
Last active May 10, 2024 21:57
Show Gist options
  • Star 23 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save heyfluke/b8372df866ec2584f9a51ca7d7fe9ebb to your computer and use it in GitHub Desktop.
Save heyfluke/b8372df866ec2584f9a51ca7d7fe9ebb to your computer and use it in GitHub Desktop.
remap docker user to host user.

Problem

When I use docker to work with the shared workspace with host under Ubuntu, I find that files created by docker user is owned by root. This is not the same with macOS.

Maybe this is becuase docker is run by root user and the default user mapping mechanism is to map container-root to host-user or host-root. So can I map the container-root or container-any-user to host-current-user?

Fortunately the latest docker supports the re-map the container user to any host user via Linux namespace. Refer to this.

Linux namespace

In the latest Linux disto (e.g Ubuntu 18) you can see the two files: /etc/subuid and /etc/subgid.

$ cat /etc/subuid
fluke:100000:65536

The file means the user fluke has a subordinate user id space starts from 100000 ends with 165535,that is, if a file is owned by uid in [100000. 165536], it's owned by fluke.

$ cat /etc/subgid
fluke:100000:65536

The rule for /etc/subgid is the same as /etc/subuid.

Isolate the docker with Linux namespace

If create or edit /etc/docker/daemon.json to add this configuration:

{
  "userns-remap": "default"
}

Then restart docker sudo service docker restart and run:

docker run ubuntu:latest -v `pwd`:/home/user touch /home/user/test_file
ls -lh test_file

We will get a test_file created by userid 165536. Because docker create a default user named dockremap with uid 165536 and re-map the container user to this user.

You can see the /etc/subuid changed by docker:

$ cat /etc/subuid
fluke:100000:65536
dockremap:165536:65536

THE SOLUTION

So what if we want to re-map the container user to current user?

It's easy. Just create a line to define a subordinate space exactly the overlap current user's uid, and tell docker to re-map to this user.

$ cat /etc/subuid
fluke:1000:1
fluke:100000:65536

and

$ cat /etc/docker/daemon.json 
{
    "userns-remap": "fluke"
}

Then restart the docker daemon. Enjoy.

Example

If you want to use a app that runs in a non-root user in container and you want it to re-map to the host-non-root user, you can use docker's run -u $USER argument to force docker to use root which will be re-map to your first subuid.

For example, if you use theia project to edit files in host directory, by default if run docker like this:

docker run -it -p 3000:3000 -v "$(pwd):/home/project:cached" theiaide/theia:next

You won't create any file is your workspace is not writable by other (e.g not 777), because theia uses a userid 1000 by default which will then be re-mapped to 101000 in the host.

You can simply solve this problem by running:

docker run -uroot -it -p 3000:3000 -v "$(pwd):/home/project:cached" theiaide/theia:next
@heyfluke
Copy link
Author

NOTE: fluke is my username.

@zombieleet
Copy link

👍

@JianhongPan
Copy link

This is not a good way because every user can still access the container built by others. Enforcement of a parameter —user=$USER when running a container can dynamically remap container to different user but docker doesn’t provide the function.

@devnoname120
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment