A lightweight, robust, flexible, and containerized NFS server.
This is the only containerized NFS server that offers all of the following features:
- NFS versions 3, 4, or both simultaneously
- optional Kerberos security
- optional name/ID mapping via
idmapd
- clean teardown of services upon
SIGTERM
orSIGKILL
(no lingeringnfsd
processes on Docker host) - flexible construction of
/etc/exports
via a Docker bind mount or environment variables - extensive server configuration via environment variables
-
The Docker host kernel will need the following kernel modules
nfs
nfsd
rpcsec_gss_krb5
(only if Kerberos is used)
Usually you can enable these modules with:
modprobe {nfs,nfsd,rpcsec_gss_krb5}
-
The container will need to run with
CAP_SYS_ADMIN
(or--privileged
). This is necessary as the server needs to mount several filesystems inside the container to support its operation, and performing mounts from inside a container is impossible without these capabilities. -
The container will need local access to the files you'd like to serve via NFS. You can use Docker volumes, bind mounts, or files baked into a custom image. e.g.
-v some_volume:/some/container/path
(Docker volume)-v /some/path/on/host:/some/container/path
(bind mount)ADD /some/path/on/host /some/container/path
(Dockerfile)
You will need to provide your desired NFS exports (/etc/exports
) upon container startup. You have three choices for doing this:
-
Bind mount
/etc/exports
into the containerdocker run \ -v /host/path/to/exports.txt:/etc/exports:ro \ -v /host/files:/nfs \ --cap-add SYS_ADMIN \ -p 2049:2049 \ erichough/nfs-server:latest
-
Provide each line of
/etc/exports
as an environment variable.The container will look for environment variables that start with
NFS_EXPORT_
and end with an integer. e.g.NFS_EXPORT_0
,NFS_EXPORT_1
, etc.docker run \ -e NFS_EXPORT_0='/nfs/foo 192.168.1.0/24(ro,no_subtree_check)' \ -e NFS_EXPORT_1='/nfs/bar 123.123.123.123/32(rw,no_subtree_check)' \ -v /host/path/foo:/nfs/foo \ -v /host/path/bar:/nfs/bar \ --cap-add SYS_ADMIN \ -p 2049:2049 \ erichough/nfs-server:latest
-
Bake
/etc/exports
into a custom imagee.g. in a
Dockerfile
:FROM ehough/nfs-server:latest ADD /host/path/to/exports.txt /etc/exports
If you'd like to run idmapd
to map between NFSv4 IDs (e.g. foo@bar.com
) and local users, simply provide idmapd.conf
and /etc/passwd
to the container. This step is required for Kerberos.
docker run \
-v /host/path/to/exports.txt:/etc/exports:ro \
-v /host/files:/nfs \
-v /host/path/to/idmapd.conf:/etc/idmapd.conf:ro \
-v /etc/passwd:/etc/passwd:ro \
--cap-add SYS_ADMIN \
-p 2049:2049 \
erichough/nfs-server:latest
You can enable Kerberos security by performing the following additional actions:
- set the environment variable
NFS_ENABLE_KERBEROS
to a non-empty value (e.g.NFS_ENABLE_KERBEROS=1
) - set the server's hostname via the
--hostname
flag - provide
/etc/krb5.keytab
which contains a principal of the formnfs/<hostname>
, where<hostname>
is the hostname you supplied in the previous step. - provide
/etc/krb5.conf
- provide
/etc/idmapd.conf
- provide
/etc/passwd
that contains your NFS client users
Here's an example:
docker run \
-v /host/path/to/exports.txt:/etc/exports:ro \
-v /host/files:/nfs \
-e NFS_ENABLE_KERBEROS=1 \
--hostname my-nfs-server.com \
-v /host/path/to/server.keytab:/etc/krb5.keytab:ro \
-v /host/path/to/server.krb5conf:/etc/krb5.conf:ro \
-v /host/path/to/idmapd.conf:/etc/idmapd.conf:ro \
-v /etc/passwd:/etc/passwd:ro \
--cap-add SYS_ADMIN \
-p 2049:2049 \
erichough/nfs-server:latest
The following optional environment variables allow you to adjust the server settings to your needs.
-
NFS_VERSION
(default is4.2
)Set to
3
,4
,4.1
, or4.2
to fine tune the NFS protocol version. Enabling any version will also enable any lesser versions. e.g.4.2
will enable versions 4.2, 4.1, 4, and 3. -
NFS_DISABLE_VERSION_3
(not set by default)Set to a non-empty value (e.g.
NFS_DISABLE_VERSION_3=1
) to disable NFS version 3 and run a version-4-only server. This setting is not compatible withNFS_VERSION=3
. -
NFS_PORT
(default is2049
)Set this to any valid port number (
1
-65535
inclusive) to changerpc.nfsd
's listening port. -
NFS_SERVER_THREAD_COUNT
(default is CPU core count)Set this to a positive integer to control how many server threads
rpc.nfsd
will use. A good minimum is one thread per CPU core, but 4 or 8 threads per core is probably better. -
NFS_PORT_MOUNTD
(default is32767
)Only needed for NFS 3. Set this to any valid port number (
1
-65535
inclusive) to changerpc.mountd
's listening port. -
NFS_PORT_STATD_IN
(default is32765
)Only needed for NFS 3. Set this to any valid port number (
1
-65535
inclusive) to changerpc.statd
's listening port. -
NFS_PORT_STATD_OUT
(default is32766
)Only needed for NFS 3. Set this to any valid port number (
1
-65535
inclusive) to changerpc.statd
's outgoing connection port. -
NFS_ENABLE_KERBEROS
(not set by default)Set to a non-empty value (e.g.
NFS_ENABLE_KERBEROS=1
) to enable Kerberos on this server. See "Kerberos" section above for further details.
# mount -o nfsvers=4 <container-IP>:/some/export /some/local/path
# docker exec -it <container-id> bash
- Running the container with
--network host
might improve network performance by 10% - 20% [1,2], though this hasn't been tested.
- switch back to Alpine Linux once this bug in
nfs-utils
is fixed - figure out why
rpc.nfsd
takes 5 minutes to startup/timeout unlessrpcbind
is running
This work was based heavily on prior projects: