8

I am new to Docker and I want to use it to get a controlled compilation environment for my code.

I already have a Docker image with all the tools I need. My problem at the moment is as follows:

  • I have my code in the host machine, inside my home folder that is mounted from an NFS server
  • I want to make this folder visible inside the Docker container with r+w permissions

Here's what I tried first (running the container with the source folder as a volume) and the error I get:

[mbrandalero@machine ~]$ docker run -it --cap-add sys_admin -v "/homes/mbrandalero/src:/usr/local/src/" mbrandalero/my-image bash
/usr/bin/docker-current: Error response from daemon: error while creating mount source path '/homes/mbrandalero/src': mkdir /homes/mbrandalero/src: permission denied.

(apparently it is trying to create the directory on the host side, but it is already there)

Curiously enough, when I try running the container with the whole home folder as a volume, it works but yields a different error (no write permission in the folder):

[mbrandalero@machine ~]$ docker run -it --cap-add sys_admin -v "/homes/mbrandalero/:/usr/local/src/home" mbrandalero/my_image bash
root@46712ad936f2:/usr/local/src# cd home/
bash: cd: home/: Permission denied
root@46712ad936f2:/usr/local/src# ls -lah | grep "\(\.\|home\)"
total 4.0K
drwxr-xr-x  1 root  root    18 May 20 14:50 .
drwxr-xr-x  1 root  root    17 May 15 14:06 ..
drwxr-x--- 30 10031 10031 4.0K May 20 15:03 home

Am I doing it right? What am I missing?

Additional informations:

  • OS: CentOS Linux 7.6
  • Docker version: 1.13.1

UPDATE (1):

Apparently setting a user id when running docker run fixes the issue, but is this the right way of doing it? Running it this way sort of fixed things, but looks odd (I get "I have no name!" as username):

[mbrandalero@machine ~]$ docker run -it --cap-add sys_admin -v "/homes/mbrandalero/:/usr/local/src/home" --user $(id -u) mbrandalero/my_image bash
I have no name!@2efec822e572:/usr/local/src$ cd home/
I have no name!@2efec822e572:/usr/local/src/home$

3 Answers 3

6

As you've noted in your update, the UID on the files is not mapped in bind mounts, this is how Linux does bind mounts. You can start the container with a different UID, but this will result in the /etc/passwd inside the container mapping to a different, or even no (in your case), user. There are various options, but my preference is to modify the container's UID with a usermod command that runs inside an entrypoint for the image with my fix-perms script. This needs to be run as root, but you can then use gosu to drop back down to the user when running your commands. I've talked about this in my dockercon presentations.


Note, instead of a bind mount to the host NFS directory, you can also do a volume mount directly the NFS server. Here are several examples of how to do that:

  # create a reusable volume
  $ docker volume create --driver local \
      --opt type=nfs \
      --opt o=nfsvers=4,addr=nfs.example.com,rw \
      --opt device=:/path/to/dir \
      foo

  # or from the docker run command
  $ docker run -it --rm \
    --mount type=volume,dst=/container/path,volume-driver=local,volume-opt=type=nfs,\"volume-opt=o=nfsvers=4,addr=nfs.example.com\",volume-opt=device=:/host/path \
    foo

  # or to create a service
  $ docker service create \
    --mount type=volume,dst=/container/path,volume-driver=local,volume-opt=type=nfs,\"volume-opt=o=nfsvers=4,addr=nfs.example.com\",volume-opt=device=:/host/path \
    foo

  # inside a docker-compose file
  ...
  volumes:
    nfs-data:
      driver: local
      driver_opts:
        type: nfs
        o: nfsvers=4,addr=nfs.example.com,rw
        device: ":/path/to/dir"
  ...
2

In the event that you are running your container as root, you may come across the error while creating mount source path ... permission denied message because the NFS host is remapping all remote root UIDs (aka. root-squash).

https://en.wikipedia.org/wiki/Unix_security#Root_squash

This is a security oriented feature that prevents a bad actor from mounting your share as their own root user, and then doing bad things with the data. As such, NFS mounts typically have the root_squash option set by default, to prevent these types of issues. In the event that you need your container to run as root, you can override this by using the no_root_squash option in your NFS host's /etc/exports file.

/srv/nfs/shared_folder <hostname>(rw,sync,no_subtree_check,no_root_squash)

http://nfs.sourceforge.net/nfs-howto/ar01s03.html

https://www.thegeekdiary.com/understanding-the-etc-exports-file/

0

This worked for me - declared the host nfs path as volume to the container. And the host nfs path is a non-home directory path, it's not a home directory.

My host nfs mount point: /mnt/abc

My docker-compose.yml file snippet.

   ...
   volumes:
  - /mnt/abc/:/abc
   ...

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .