16

Is there any way to mount a named volume as a non-root user? I am trying to avoid having to run a chown in each Dockerfile but I need the mount to be writable by a non-root user to be able to write the artifacts created by a build in the image

This is what I'm trying

docker run --rm -it -v /home/bob/dev/:/src/dev -v builds:/mnt/build --name build hilikus/build /bin/bash

but for the second mount I get

[user@42f237282128 ~]$ ll /mnt
total 4
drwxr-xr-x 2 root root 4096 Sep 18 19:29 build

My other mount (/src/dev/) is owned by user, not by root so it gives what I need; however, I haven't been able to do the same with the named volume.

Hilikus
  • 9,954
  • 14
  • 65
  • 118

3 Answers3

5

The named volume initializes to the contents of your image at that location, so you need to set the permissions inside your Dockerfile:

$ cat df.vf-uid
FROM busybox
RUN mkdir -p /data && echo "hello world" > /data/hello && chown -R 1000 /data

$ docker build -t test-vf -f df.vf-uid .
Sending build context to Docker daemon 23.06 MB
Step 1 : FROM busybox
 ---> 2b8fd9751c4c
Step 2 : RUN mkdir -p /data && echo "hello world" > /data/hello && chown -R 1000 /data
 ---> Using cache
 ---> 41390b132940
Successfully built 41390b132940

$ docker run -v test-vol:/data --rm -it test-vf ls -alR /data
/data:
total 12
drwxr-xr-x    2 1000     root          4096 Sep 19 15:26 .
drwxr-xr-x   19 root     root          4096 Sep 19 15:26 ..
-rw-r--r--    1 1000     root            12 Aug 22 11:43 hello
BMitch
  • 231,797
  • 42
  • 475
  • 450
  • Very strange, I've a similar Dockerfile as you, but I have this extra instructions `VOLUME /data`, when I do the `docker run` as you show, everything is back to `root` ownership (note that another difference is that my volume is empty at start, so I only change the volume folder ownership. – Huygens Aug 27 '17 at 18:20
  • 1
    I "took the bull by the horn" as we say here! I overlooked the documentation on `Dockerfile` it states `Changing the volume from within the Dockerfile: If any build steps change the data within the volume after it has been declared, those changes will be discarded.` I just had that! The VOLUME instruction was before I created the folder and set the permissions. It was simply discarded. – Huygens Aug 27 '17 at 18:54
  • 1
    @Huygens I have a personal best practice to not mix Volumes with a Dockerfile. See my blog post for the full explanation, but you hit on one of the big issues already: https://boxboat.com/2017/01/23/volumes-and-dockerfiles-dont-mix/ – BMitch Aug 27 '17 at 20:16
  • The added value of having them declared in the Dockerfile is mostly 2 things: it persists the data even if you forgot to provide volume in `docker run` (and one understand that named volumes are auto-created); wrappers can propose automatically users to create volumes by simply inspecting the image (no need for doc). But if you provide good docs, then those 2 points are not so relevant and can be considered optional. All this to tell you that yes I agree with your best practice, it brings more advantages (or less headaches). – Huygens Aug 28 '17 at 18:30
  • I seems to work for a named volume used in a single container, where I set the permissions in the Dockefile. But what if I use a named volume in two containers? Which Dockerfile or which image respectively would be responsible for the permissions of the volume? – Dario Seidl Oct 02 '20 at 15:28
  • 1
    @DarioSeidl whichever starts first, and once the volume is initialized it won't be initialized again by an update to the image or using the volume with a different image. – BMitch Oct 02 '20 at 16:06
0

If you use the new --mount syntax instead of the old -v/--volume syntax it is supposedly possible to assign a uid to the volume's contents via docker volume create somename --opt -o=uid=1000 or something similar.

See https://docs.docker.com/engine/reference/commandline/volume_create/#driver-specific-options

I haven't fully tested this to run as non-root or using the dockremap dynamic user with the userns-map option but hope to soon.

dragon788
  • 3,583
  • 1
  • 40
  • 49
  • Nope. Good guess, but `uid` is not accepted by either `docker volume create` or `docker run --mount`. – corwin.amber May 11 '22 at 20:22
  • @corwin.amber did you read the docs, you can't directly pass `--uid=nnn` you have to pass `-o=uid=nnnn` and it depends on the storage driver you are using. – dragon788 May 15 '22 at 18:21
  • Yes of course. The former `--uid` gives (expectedly) an `unknown flag` error. The latter gives `Error response from daemon ... invalid option: "uid"`. Sorry. – corwin.amber May 16 '22 at 08:54
0

You can run the following docker command and change the ownership like so:

docker run --rm -v builds:/target alpine:latest sh -c 'chown 1000:1000 /target'

The command will create the "builds" named volume, mount it to a tiny container running as root, and change its ownership to user id 1000.

Now when mounting the named volume on your container, it will be mounted as non-root

Arik
  • 5,266
  • 1
  • 27
  • 26