-
Notifications
You must be signed in to change notification settings - Fork 302
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rootless docker mounts have the wrong permissions #4646
Comments
With two UIDs (root and the regular user) in the container, you probably need to map these to two UIDs on the host. Is there a way to control that mapping with Docker? |
sort of You have to manually set up remapping like this, I think - although note the permissions don't actually reflect the "real" user (this is based on the namespacing feature). That's not really tenable. |
I think you could add the host UID of the container user to the host folder's owning group to make that folder writeable from within the container. Haven't tried yet myself. |
.... can you even add a non-existent user to a group? Otherwise you're having to set up the same set of ids as that example I linked. Even then, this likely requires |
@chrmarti I was actually talking with @egamma about rootless support since I'd love to start making this the default recommendation for Linux users given the security benifits it provides. (I mean, one of the reasons Podman exists is to solve this historic Docker problem.) The issue here is that IDs get remaped a bit more like we see on Windows and macOS historically. However, by default, everything lands as root which sucks. I've got an env setup this way and have 1000:1000 both inside and outside the container and have this problem as well. It's a different mode entirely. To get things to work like they have historically, you need to add the following to the run command (or in Docker Compose): The one other bug is we appear to be not respecting |
Would One issue might be that if we need 2 users (root and 1000) in the container, we also need 2 users to map to on the host. (I might be wrong on this though, I haven't explored rootless much yet.) |
@chrmarti The daemon is still running as your user, but I'm not confident enough to say for sure what the impact is - one of the reasons I tried to spin it up that way. I also walked the docker source code and it doesn't look like you can pass in an arbitrary namespace into the argument. Given the way rootless passes in the current user, it maps root to my local user (0 to 1000), so trying to expand the subuid range doesn't work ... docker bombs on start. I'm almost wondering if the correct solution has to be to run the docker engine as another non-root user (e.g called "docker-root") which then should allow you to update Aside from this permissions issue, things appeared to work as expected otherwise, so at a minimum getting the socket fix in for volumes would unblock that in the configuration here. |
@chrmarti Near as I can tell, this can't be resolved with rootless docker. I suspect Docker needs to add the equivalent of keep-id (and may even require changes to rootlesskit). I was able to get a separate user up running rootless docker, add an ACL to the docker socket to let another user use it, and get a user other than root for the bind mount, but it wasn't the same user ID and it was really hacky. If you restarted docker, you need to reapply the ACL. Just adding the user to a docker group doesn't work, because the GID on the socket isn't the typical "docker" one but a gid mapped one. Even if you do that, the other user does not (by design) have access to /run/root/ for the other user by default. Maybe there's some other option but I'm not seeing it at this moment. So, I think volumes is the best recommendation in a rootless configuration at the moment unless you want to run as "root" in the container. That does work, but obviously can pose other issues. |
So to rephrase: The way Docker implements rootless works well only when using root (mapped to the local user locally) inside the container? And this might be more general than just with how Docker is approaching this because there is no way to map two container user ids to a single host user id? (Partly because the reverse mapping must be unique.) |
Yeah, but there's a bit more since I tried to work around that. To recap: You can use a different nonroot user inside the container, but bind mounts come across with translated IDs. When the IDs are the same user as the rootless docker daemon is running as, that translated ID will be In the experiment above, what I did was create a user with UID In concept, we could alter the container user's UID here, but the ACL has to be re-applied each time docker starts in this configuration. So I'm a bit stumped at the moment. |
.... which means that you now have two copies of the repository in play (local and volume). Or you need to build the container ahead of time (or get it from a registry). Even then, though, this isn't going to work for all projects - my current projects, for example, are doing graphics work, and so sometimes need access to the X11 socket (the deployed project is targeting EGL, so I don't require it for the built final product, but it's necessary for tools and debug output). |
@Clockwork-Muse "Clone Repository in Container" supports the same container editing flow as using local bind mounts. So you don't need to do anything ahead of time. You'd be prompted as usual and can use the rebuild flow. That said, yes, you end up with the source in a docker volume. Interestingly, running as root in the container works fine with bind mounts and will not cause the historic problem of the wrong UID/GID being used. It maps to your local user. Docker (really rootlesskit) seems to hard code the mapping of your local user UID/GID to |
@Chuxel Any news on this about non root user in the container with rootless Docker? |
P.s. I found this upstream ticket moby/moby#41497 |
To my knowledge, this simply isn't possible. You need to use root when running rootless with bind mounts. |
does it means must be in non-root(rootfull) mode? still not support rootless yet? |
It works if you use root inside the container. Root in the container is mapped to your regular user on the host and with that the files in the bind mounts (e.g., the workspace folder) have the correct UID/GID (again root inside the container and regular user on host). |
@chrmarti So what is this the general recommendation? Log in as root? Would the remote container feature be documented for rootless docker? |
@yaroslavsadin I don't think we have a good answer yet. The problem is that there is a single user on the host for which there are two users (root and the regular user) inside the container and there does not seem to be a way for "rootless" to map the two users inside the container to the single user on the host. (Which seems to make sense because the reverse mapping wouldn't know to which of the two container users to map to.) |
The recommendation here likely needs to be to use "clone repository in contianer" volume and to then we need explore ways to move local content into a volume on create. #7184 also needs to be resolved. The only other option is to run as root in the container. |
I suppose that it is already supported in podman with |
Yeah the question here was with docker specifically. Podman drives different challenges. But, part of the reason that the dev container CLI is OSS (https://github.com/devcontainers/cli) is to allow the community to contribute support for alternatives where needed or to target tough problems that do not show up broadly. This extension uses the CLI under the hood. Outside of the simple scenarios, each engine seems to have their differences and related challenges. They aren't full drop-ins unfortunately. Unfortunately, for this particular case, there isn't a good answer for the Docker engine. |
Any update on this? I'm having the same issue with Docker. |
Dear all, as a user of devcontainer with rootless docker and have already struggled with the issues discussed here, I'll share 4 different solutions I've found to deal with this situation (considering Linux/Ubuntu 22.04 with local user called "hostuser" with id 1001, which is non-standard and slightly more challenging that typical 1000 user):
Possible Solution 1) docker rootless - use root on container: Possible Solution 2) docker rootless - use vscode user on container and chown your files: Now, consider the following matching of subuid:
Your projectfolder files should become Now your files are back to your user domain. It means that docker works like this: root (0) on container means (hostuser) 1001 outside; and vscode user (1001) inside means Possible Solution 3) use podman rootless -
Although Possible Solution 4) use podman rootless - matching ids with
With this option, you log as
It means that all files are accessible in host, even root-created ones. So, for podman, all other configurations I tried with different remoteUser, containerUser and userns got all innefective or inconsistent/broken, so I only recommend these two above. In short, I manage to make things work, and usually adopt either Solution 1 (root on docker rootless), or Solution 4 (userns on podman rootless), so I would recommend the extension to:
Finally, I also manage to work with "docker-from-docker" (or Dood) on docker rootless (note that docker-in-docker "dind" typically won't work due to the lack of
and injecting variable |
Yeah, the core idea behind rootless is to allow you to use root within the container, so that's always the path of least resistance. This is one of the reasons that we try to ensure both the root and non-root user work as expected in images and Features. FWIW - All of this logic is in the open source CLI. So PRs are welcome to make improvements like these. https://github.com/devcontainers/cli |
In fact @chrmarti , both podman and docker seem to use similar strategies, as each subuser must have a matching id on host. Only the count is slightly different. Consider the following:
for docker and rootlesskit, it seems to map:
for podman
So, the convenience of podman is that it really matches the file uid of host and container with exactly the same number, while docker implicitly considers 0 of container to be host uid... So, effective change in file ids could be necessary to work as non-root docker rootless container (as requested in this issue), such as |
vscode connects as a user 'vscode', while it needs to connect as 'root' to have the correct permissions. (This is root user in the container, not the root user on the host. so should be fine security-wise. |
@ajoshiusc - Yes, uid mapping means that maps to the external user uid... Which is why mapping the internal uid to the external uid is vastly better. |
Another scenario: i usually use podman instead of docker. I also installed rootless docker and it can run side by side - except under VSCode Dev Container Extension. I need to run rootful docker (in a Lima VM or where-so-ever) since I do run a terraform project which just assumes rootful docker and nothing else (wich is also default for most of our developers) :/ I used following by
But unfortunately the result is:
Also when I add
Within the container I get:
And it is run as rootless container. I tried to wrap vscode in en execution environment (unsetting DOCKER_HOST export DOCKER_CONTEXT). While the build happens on rootful docker execution is still happening in rootless docker. TL;DR This really needs to improve. Also general support for rootless. It doesn't make sense to base something on container environment when users are forced to run in rootful environments (even if thats in a VM, but again containers vs VM??!) |
We have been using devcontainers and podman for a few years now. Early on, we settled on the default behavior of being root inside the container and that has been very successful. Root is mapped to the host user when accessing host mounts. (Luckily we have not needed to use any containers that require rootful.) For most of this time we have not been using the Microsoft Developer Container base images. However yesterday I was experimenting with mcr.microsoft.com/vscode/devcontainers/base:ubuntu-24.04. I found that it works fine with both rootless podman and rootless docker as long as I add these settings: This very simple example project https://github.com/gilesknap/docker-outside-docker has the following features:
As far as my experience goes, rootless docker and podman have very similar behavior with the important caveat that --net host does not work for rootless docker. |
As of Docker CE 20.10.0 (2020-12-08), support for docker to run rootless has moved out of experimental status and into mainline. While remote containers work, the namespace remapping means that any mounted directories end up with the root uid (uid 0), and so any container user (eg, via
containerUser
orremoteUser
) lacks the permissions to modify these files/directories.Steps to Reproduce:
docker
group and adding the user).Ctrl+Shift+P
->Remote Containers: Add Development Container Configuration Files
->Alpine
Ctrl+Shift+P
->Remote Containers: Rebuild and Reopen in Container
Strictly speaking, this is probably more a docker configuration issue. Unfortunately docker doesn't seem to have an equivalent to podman's
--userns=keep-id
(as is mentioned in some of the issues on here). Although my current project allows me to use a workaround of running as the container root, this isn't possible for everything (and does mean that some aspects of the development environment would no longer match any deployment environment).Does this issue occur when you try this locally?: No
Does this issue occur when you try this locally and all extensions are disabled?: No
The text was updated successfully, but these errors were encountered: