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
SIGTERMorSIGKILL(no lingeringnfsdprocesses on Docker host) - flexible construction of
/etc/exportsvia a Docker bind mount or environment variables - extensive server configuration via environment variables
-
The Docker host kernel will need the following kernel modules
nfsnfsdrpcsec_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/exportsinto 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/exportsas 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/exportsinto 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. [email protected]) 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_KERBEROSto a non-empty value (e.g.NFS_ENABLE_KERBEROS=1) - set the server's hostname via the
--hostnameflag - provide
/etc/krb5.keytabwhich 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/passwdthat 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.2to fine tune the NFS protocol version. Enabling any version will also enable any lesser versions. e.g.4.2will 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-65535inclusive) 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.nfsdwill 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-65535inclusive) 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-65535inclusive) 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-65535inclusive) 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 hostmight improve network performance by 10% - 20% [1,2], though this hasn't been tested.
- switch back to Alpine Linux once this bug in
nfs-utilsis fixed - figure out why
rpc.nfsdtakes 5 minutes to startup/timeout unlessrpcbindis running
This work was based heavily on prior projects: