Skip to content
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

Add ability to mount volume as user other than root #2259

Open
mingfang opened this issue Oct 17, 2013 · 148 comments
Open

Add ability to mount volume as user other than root #2259

mingfang opened this issue Oct 17, 2013 · 148 comments

Comments

@mingfang
Copy link

@mingfang mingfang commented Oct 17, 2013

Use case: mount a volume from host to container for use by apache as www user.
The problem is currently all mounts are mounted as root inside the container.
For example, this command
docker run -v /tmp:/var/www ubuntu stat -c "%U %G" /var/www
will print "root root"

I need to mount it as user www inside the container.

@jpetazzo
Copy link
Contributor

@jpetazzo jpetazzo commented Oct 18, 2013

If you chown the volume (on the host side) before bind-mounting it, it will work.
In that case, you could do:

mkdir /tmp/www
chown 101:101 /tmp/www
docker run -v /tmp/www:/var/www ubuntu stat -c "%U %G" /var/www

(Assuming that 101:101 is the UID:GID of the www-data user in your container.)

Another possibility is to do the bind-mount, then chown inside the container.

@crosbymichael
Copy link
Member

@crosbymichael crosbymichael commented Nov 28, 2013

@mingfang Will chown not work for you ?

@bfirsh
Copy link
Contributor

@bfirsh bfirsh commented Jan 17, 2014

It would be useful to have a shortcut for this. I often find myself writing run scripts that just set the permissions on a volume:

https://github.com/orchardup/docker-redis/blob/07b65befbd69d9118e6c089e8616d48fe76232fd/run

@aldanor
Copy link

@aldanor aldanor commented Feb 18, 2014

What if you don't have the rights to chown it?

@cpuguy83 cpuguy83 mentioned this issue Jun 18, 2014
7 of 12 tasks complete
@iwinux
Copy link

@iwinux iwinux commented Jun 26, 2014

Would a helper script that chown the volume solve this problem? This scirpt can be the ENTRYPOINT of your Dockerfile.

@SvenDowideit
Copy link
Contributor

@SvenDowideit SvenDowideit commented Jul 8, 2014

Can I say no - forcing users to add a helper script that does

#!/bin/sh
chown -R redis:redis /var/lib/redis
exec sudo -u redis /usr/bin/redis-server

(thanks @bfirsh for your eg)

is pretty terrible.

It means that the container has to be started as root, rather than running as the intended redis user. (as @aldanor alluded to )

and it means a user can't do something like:

docker run -v /home/user/.app_cfg/ -u user application_container application :(

@SvenDowideit
Copy link
Contributor

@SvenDowideit SvenDowideit commented Jul 8, 2014

There is one way to make it work, but you need to prepare ahead of time inside your Dockrfile.

RUN mkdir -p /var/lib/redis ; chown -R redis:redis /var/lib/redis
VOLUME ["/var/lib/redis"]
ENTRYPOINT ["usr/bin/redis-server"]
USER redis

(I didn't test this example, I'm working on a chromium container that then displays on a separate X11 container that .... )

@tianon
Copy link
Member

@tianon tianon commented Jul 10, 2014

And of course that method only works for direct new volumes, not bind
mounted or volumes-from volumes. ;)

@thaJeztah
Copy link
Member

@thaJeztah thaJeztah commented Jul 14, 2014

Additionally, multiple containers using volumes-from will have different uid/gid for the same user, which complicates stuff as well.

@frankamp
Copy link

@frankamp frankamp commented Aug 7, 2014

@SvenDowideit @tianon that method doesn't work either. Full example:

FROM ubuntu
RUN groupadd -r redis    -g 433 && \
useradd -u 431 -r -g redis -d /app -s /sbin/nologin -c "Docker image user" redis 
RUN mkdir -p /var/lib/redis
RUN echo "thing" > /var/lib/redis/thing.txt
RUN chown -R redis:redis /var/lib/redis
VOLUME ["/var/lib/redis"]
USER redis
CMD /bin/ls -lah /var/lib/redis

Two runs, with and without a -v volume:

bash-3.2$ docker run -v `pwd`:/var/lib/redis voltest 
total 8.0K
drwxr-xr-x  1 root root  102 Aug  7 21:30 .
drwxr-xr-x 28 root root 4.0K Aug  7 21:26 ..
-rw-r--r--  1 root root  312 Aug  7 21:30 Dockerfile
bash-3.2$ docker run  voltest 
total 12K
drwxr-xr-x  2 redis redis 4.0K Aug  7 21:30 .
drwxr-xr-x 28 root  root  4.0K Aug  7 21:26 ..
-rw-r--r--  1 redis redis    6 Aug  7 21:26 thing.txt
bash-3.2$ 
@andrewmichaelsmith
Copy link

@andrewmichaelsmith andrewmichaelsmith commented Nov 13, 2014

We're hitting an issue that would be solved by this (I think). We have an NFS share for our developer's home directories. Developers want to mount /home/dev/git/project in to Docker but cannot because we have Root Squash enabled.

This forbids root from accessing /home/dev/git/project so when I try and run docker mounting /home/dev/git/project I get an lstat permission denied error.

@cpuguy83
Copy link
Contributor

@cpuguy83 cpuguy83 commented Nov 13, 2014

@frankamp This is because docker's current preference is to not modify host things which are not within Docker's own control.

Your "VOLUME" definition is being overwritten by your -v pwd`:/var/lib/reds`.
But in your 2nd run, it is using a docker controlled volume, which is created in /var/lib/docker. When the container starts, docker is copying the data from the image into the volume, then chowning the volume with the uid:gid of the dir the volume was specified for.

I'm not sure there is much that can be done here, and unfortunately bind mounts do not support (as far as I can tell) mounting as a different uid/gid.

@ebuchman
Copy link

@ebuchman ebuchman commented Jun 13, 2015

My solution to this was to do what SvenDowideit did above (create new user and chown up front in dockerfile), but then instead of mounting the host volume, use a data-only container, and copy the host volume I wanted to mount into the container with tar cf - . | docker run -i --volumes-from app_data app tar xvf - -C /data. This will become a tad easier once #13171 is merged (and docker cp works both ways), but perhaps it could become an alternative to -v host_dir:container_dir, ie. maybe -vc host_dir:container_dir, (vc for volume-copy), wherein the host_dir's contents would get copied into the data container. Though I can't say I understand why/how the copied files inherit the container user's permissions, from what I can tell they do, and this is the only reasonable solution I've managed to come up with that doesn't destroy portability.

@jsdevel
Copy link

@jsdevel jsdevel commented Dec 7, 2015

What about acl?

@calvix
Copy link

@calvix calvix commented Jan 6, 2016

Is there any fix or workaround? I run into same issue with OpenShift, mounted folder is owned by root:root and precreated images wont work.

@brikis98
Copy link

@brikis98 brikis98 commented Jan 21, 2016

I'm looking for a workaround too. If all mounted volumes are owned by root, it makes it impossible to run your Docker containers with any user other than root.

@dreamcat4
Copy link

@dreamcat4 dreamcat4 commented Jan 21, 2016

Well you can try s6-overlay. It includes features which are specifically targeted to help to work-around these kinds of problems.

@brikis98
Copy link

@brikis98 brikis98 commented Jan 21, 2016

@dreamcat4: Thanks for the pointer. The fixing ownership & permissions seems like an interesting workaround, but wouldn't I have to run my Docker container as root for that to work?

@dreamcat4
Copy link

@dreamcat4 dreamcat4 commented Jan 21, 2016

@brikis98 Yes that is true. However s6-overlay also has yet another feature, which allows you to drop the permissions back again when launching your servers / daemons.

@brikis98
Copy link

@brikis98 brikis98 commented Jan 21, 2016

@dreamcat4 Ah, gotcha, thanks.

@alexanderadam
Copy link

@alexanderadam alexanderadam commented Jun 27, 2019

Docker had this particular issue open since 2013 and nearly six years later there is no easy improvement in sight. Podman was designed to gain compatibility with Docker but solve the design flaws of Docker as well (including running as an unprivileged user that won't require a superuser Docker daemon).

If users are able to giver others an advice on a GitHub issue that's totally fine. This is a community. Feel free to recommend whatever could be helpful.

I can assure you there are a lot of reasons for why Docker is structured the way it is

So is grep. But if someone needs to search faster I would still recommend ripgrep. Even on the grep issue tracker. It shouldn't matter whose issue tracker it is, as long as it solves the problem of the users and makes them happy.

If Podman doesn't work for you: fine! But if helps others because they just have to replace docker with podman in their infrastructure: just let them do so.

@SuperSandro2000
Copy link

@SuperSandro2000 SuperSandro2000 commented Jun 27, 2019

Podmans main argument is that it does not run a daemon and that is my main argument against it. How do I get my container back up after a reboot? I won't do it by hand and everything else is just bad design. Also I don't want my docker container owned by a user but owned by the system and this means root.
Podman makes sense if you are the only person using it.

And to fix your problem: Build a container with COPY --chown ...:...!

Also Docker has not such problems and you can remotely control docker servers which is important for me, too.

There are tools to generate pods from running containers, too which I won't recommend cause you should build them from the ground up in a clean way.

@alexanderadam
Copy link

@alexanderadam alexanderadam commented Jun 27, 2019

I guess we should go back on topic now: IMHO the first advice was okay but everything else just blows this issue up and won't solve anything.

@SuperSandro2000, you can click here for the response on your statements, though.

How do I get my container back up after a reboot? I won't do it by hand and everything else is just bad design.

Well, Podman has native integration with systemd (like nearly every other thing on nearly all modern GNU Linux distributions). So you don't have to maintain 'two' booting systems (like first having systemd to start the Docker daemon which then have to make another round of starting containers in a different configuration). So with Podman you can control everything with systemd (meaning: the system you most probably already have installed and running anyway).

Also I don't want my docker container owned by a user but owned by the system and this means root.

It is totally fine if you don't want it. You are still able to run Podman as superuser but you don't have to anymore. In general it is considered a bad idea and increases the attack surface because if someone is able to exploit your Docker daemon, he has control about everything on on the system.

Podman makes sense if you are the only person using it.

This statement does not make any sense. Podman enables you to spread up on a single system which is a feature that especially makes sense if you have many people working on the same system.

And to fix your problem: Build a container with COPY --chown ...:...!

IMHO the issue here is mounting a volume for a container on runtime. Which has only little to do with building an image.

Also Docker has not such problems and you can remotely control docker servers which is important for me, too.

Funny that you mention exactly the blog that has this post in it. However I'm not very experienced with network details of both implementations but as I understood, podman starts with the least possible network rules and unprivileged users cannot set up veth pairs

@cpuguy83
Copy link
Contributor

@cpuguy83 cpuguy83 commented Jun 27, 2019

@SuperSandro2000
Copy link

@SuperSandro2000 SuperSandro2000 commented Jun 28, 2019

@alexanderadam

IMHO the issue here is mounting a volume for a container on runtime. Which has only little to do with building an image.

My solution was to no mount the directory but bake it in the container if it is possible.

I mean podman sounds good but I won't switch cause for now I do not see any advantage for me. Thanks for the explanation anyway.

@abitrolly
Copy link

@abitrolly abitrolly commented Sep 13, 2019

podman suffers from the same problem if Apache inside container is run under www user. containers/libpod#3990

The solution could be to map www user from container to UID on the host if there is no root user inside container. I do not know if that is possible.

shaybensasson added a commit to shaybensasson/Docker that referenced this issue Sep 26, 2019
* It turn out there is a major unsolved problem with dockers with non root users and volumes bound to host dir:
moby/moby#2259

see README.md
@yngvark
Copy link

@yngvark yngvark commented Nov 5, 2019

If you want to run with --read-only (to do the same as the readOnlyRootFilesystem Kubernetes policy), it's possible to do the below. It builds on the workaround @jpetazzo was suggesting:

  • My docker image creates and uses a user with uid=1001 and gid=1001
  • Separately, create a docker volume
  • Chown the uid:gid to 1001
  • Mount that image when running the application.

Dockerfile:

FROM ubuntu

RUN groupadd -g 1001 appgroup && \
    useradd -u 1001 -g appgroup appuser

USER appuser

Then:

$ docker build . -t test
$ docker volume create somedir
$ docker run -v somedir:/some_dir alpine chown -R 1001:1001 /some_dir

Now, when running the docker image and mounting the volume, /some_dir belongs to the user I want.

$ docker run -it --read-only -v somedir:/some_dir test ls -lrt

...
dr-xr-xr-x  13 root    root        0 Nov  4 15:22 sys
drwxr-xr-x   2 appuser appgroup 4096 Nov  5 09:45 some_dir
drwxr-xr-x   1 root    root     4096 Nov  5 09:45 etc
...

$ docker run -it --read-only -v somedir:/some_dir test touch /some_dir/hello
$ docker run -it --read-only -v somedir:/some_dir test ls -lrt /some_dir

-rw-r--r-- 1 appuser appgroup 0 Nov  5 09:52 hello

@nagstaku
Copy link

@nagstaku nagstaku commented Nov 20, 2019

I'll point out again, because it is easily lost in the thread, that a chowned symlink will probably work for most scenarios. The downside being that you need someway of setting it up, which often means replacing the entrypoint with a script that then runs the original command.

#2259 (comment)

gerrywastaken added a commit to gerrywastaken/gencert that referenced this issue Jan 19, 2020
I'm adding a lot of complication here simply because Docker doesn't
allow us to creat something in a container and expose it in a volume on
the host while making the files owned by the current user.

More info
---------
moby/moby#2259
title: Add ability to mount volume as user other than root
date: 2013-10-17

https://medium.com/faun/set-current-host-user-for-docker-container-4e521cef9ffc
title: Set current host user for docker container
author: Lenty Chang
date: 2019-04-07
@squatica squatica mentioned this issue Feb 14, 2020
@abinax
Copy link

@abinax abinax commented Feb 20, 2020

+1

seriema added a commit to seriema/retro-cloud that referenced this issue Mar 26, 2020
Happens when mounting the VM share in mount-vm-share.sh.

The issue has two parts:
1. "pi" does not have write access to `/dev/fuse`, not even with sudo,
   so mount-vm-share.sh fails to mount the drive.
2. `/dev/fuse` does not exist until runtime so it's not accessible when
   building the Docker image.

The easiset solution is to give back root-membership to "pi". It was
removed in the switch from `useradd` to `adduser` in PR #8 (67a9067).

Not the same, but there might be something to learn from Docker's
requirement on root access for mounting volumes:
moby/moby#2259

Note: The "pi" user on a real RetroPie installation on a RPi is _not_
member of root. So this solution should be removed one day.

Cleaned up Dockerfile. The instructions will be added to Readme.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
You can’t perform that action at this time.