50

Does anyone know how to mount nfs share inside docker container with centos base image? I've tried this command:

mount server:/dir /mount/point

and got the next error:

mount.nfs: rpc.statd is not running but is required for remote locking.
mount.nfs: Either use '-o nolock' to keep locks local, or start statd.
mount.nfs: an incorrect mount option was specified

when I try to use it with -o nolock option, the error is:

mount.nfs: Operation not permitted
Anatoli
  • 889
  • 2
  • 15
  • 33
  • You can refer to the link below. https://stackoverflow.com/questions/45282608/how-to-directly-mount-nfs-share-volume-in-container-using-docker-compose-v3?answertab=votes#tab-top – tony Oct 13 '19 at 08:51

5 Answers5

85

Starting from docker 17.06, you can mount NFS shares to the container directly when you run it, without the need of extra capabilities

export NFS_VOL_NAME=mynfs
export NFS_LOCAL_MNT=/mnt/mynfs
export NFS_SERVER=my.nfs.server.com
export NFS_SHARE=/my/server/path
export NFS_OPTS=vers=4,soft

docker run --mount \
  "src=$NFS_VOL_NAME,dst=$NFS_LOCAL_MNT,volume-opt=device=:$NFS_SHARE,\"volume-opt=o=addr=$NFS_SERVER,$NFS_OPTS\",type=volume,volume-driver=local,volume-opt=type=nfs" \
  busybox ls $NFS_LOCAL_MNT

Alternatively, you can create the volume before the container:

docker volume create \
  --driver local \
  --opt type=nfs \
  --opt o=addr=$NFS_SERVER,$NFS_OPTS \
  --opt device=:$NFS_SHARE \
  $NFS_VOL_NAME

docker run --rm -v $NFS_VOL_NAME:$NFS_LOCAL_MNT busybox ls $NFS_LOCAL_MNT
Trevor Boyd Smith
  • 18,164
  • 32
  • 127
  • 177
ThiagoAlves
  • 1,313
  • 16
  • 25
  • 3
    This should be the #1 answer from Docker 17.06 and beyond. I was waiting a long time for this capability! – Slack Flag Nov 22 '17 at 13:36
  • 1
    I have edited the answer to fix a typo and highlight the parameters that people normally want to customize (local mount point in container, NFS server hostname / IP and remote NFS share path) – ThiagoAlves Nov 24 '17 at 18:28
  • 1
    I'm still trying to understand the embedded mount options, but it looks like this one is working for me. I really like that it's idempotently creating the volume in the process of creating the mount for the container. – rubicks May 01 '18 at 14:28
  • 1
    Can you use this same method with bind mounts instead of volumes? – Bort May 31 '18 at 17:37
  • Doing exactly what you wrote I get `no such file or directory` although I can use the exactly same setup to mount manually from my host. – pbn Apr 03 '19 at 13:23
50

For using mount, you'll need the CAP_SYS_ADMIN capability, which is dropped by Docker when creating the container.

There are several solutions for this:

  1. Start the container with the --cap-add sys_admin flag. This causes Docker to retain the CAP_SYS_ADMIN capability, which should allow you to mount a NFS share from within the container. This might be a security issue; do not do this in untrusted containers. [A previous version of this answer suggested using the --privileged=true to retain all capabilities, thanks to @earcam for the suggestion to use --cap-add instead].
  2. Mount the NFS share on the host and pass it into the container as a host volume:

    you@host > mount server:/dir /path/to/mount/point
    you@host > docker run -v /path/to/mount/point:/path/to/mount/point
    
  3. Use a Docker volume plugin (like the Netshare plugin) to directly mount the NFS share as a container volume:

    you@host > docker run \
      --volume-driver=nfs \
      -v server/dir:/path/to/mount/point \
      centos
    
helmbert
  • 35,797
  • 13
  • 82
  • 95
  • For option 1: How to workaround when not using `--privileged=true`? – Zelphir Kaltstahl Jan 31 '17 at 10:01
  • 3
    Method 2. does not seem to work. I have the NFS mounted on the local system and I can see all the files. However when I pass the mount folder to the container as a volume, I only get an empty folder. I have tries changing permissions as Jing Qiu suggested, without success. – cage Apr 10 '17 at 09:13
  • I get following error on Method 1. `mount.nfs: rpc.statd is not running but is required for remote locking. mount.nfs: Either use '-o nolock' to keep locks local, or start statd. mount.nfs: an incorrect mount option was specified` – Coder Jun 26 '18 at 01:17
  • 1
    (in 2019) `--cap-add` gives finer grained control than `--privileged=true` – earcam Jan 20 '19 at 22:17
  • 1
    @earcam Thanks for the suggestion! I've incorporated it into my answer. – helmbert Jan 21 '19 at 10:56
  • 1
    Hi @helmbert, I'm having issues with your suggestion #2, some containers need to chown files they create in the mounted directories. However, NFS doesn't allow this from what I've found. Have you found a workaround for this or have you not encountered any containers that do this? – dalanmiller Mar 30 '19 at 22:29
  • You can't see the files within the container because the container is unaware that NFS exists - because is running on the host. Since the container doesn't have access to it, the files in your mount path will be invisible to it regardless of the permissions the files may or may not have. A better solution would be to create (mkdir) the path on your host, link them to your container with a volume and do `mount.nfs` within your container. If you do this, the opposite thing will happen - you'll see the files from within the container but not in the host. Cheers! – memozac Jan 14 '20 at 19:15
11

For the second option listed in the accepted answer, I'm not sure if you have actually tried to use the "docker run -v" command to pass a NFS share on the host to docker container as a volume. I have recently tried to do so, below is the info for the nfs share on host:

nfs-server:/path_to_mount on /path_dest type nfs

and then:

docker run -it -v /path_dest:/path_in_docker docker_name bash

But the docker daemon always reports below error:

docker: Error response from daemon: stat /path_dest: permission denied.

After many searches, I found that the error actually comes from docker daemon, which is running as "root". When docker runs a container with volume to mount, it will request docker daemon to mount it. The problem is, NFS server will handle "root" differently. By default, NFS server will map the "root" to "nobody", causing the error message: reference

Jing Qiu
  • 533
  • 4
  • 11
2

I mount the nfs on docker container, thanks for @helmbert .

  1. Run a docker container with the --privileged=true flag.

    $ docker run -it --privileged=true centos:7 bash
    [root@f7915ae635aa /]# yum install -y nfs-utils
    
  2. Install the nfs tool package and mount nfs on CentOS.

    [root@f7915ae635aa /]# yum install -y nfs-utils
    [root@f7915ae635aa /]# mount -t nfs example.tw:/target/ /srv -o nolock
    
  3. Show mount of the nfs server.

    [root@f7915ae635aa /]# showmount example.tw
    Hosts on example.tw:
    10.10.10.1
    10.10.10.2
    
Chu-Siang Lai
  • 2,658
  • 1
  • 24
  • 21
1

By adding --cap-add sys_admin flag to client container wasn't enough for me. I was getting error:

mount.nfs: mount(2): Permission denied
mount.nfs: access denied by server while mounting 1.2.3.4:/exports

After hours of research I've found that it looks like full privilege --privileged is needed to mount correctly inside docker container ..

Also don't forget to install necessary nfs client packages inside your docker container. On debian based containers:

apt-get install -y nfs-common
Shinebayar G
  • 4,624
  • 4
  • 18
  • 29