Skip to content
This repository was archived by the owner on Oct 6, 2023. It is now read-only.

Commit 51950dc

Browse files
committed
overhaul and split up docs
1 parent f1b2e05 commit 51950dc

File tree

8 files changed

+199
-118
lines changed

8 files changed

+199
-118
lines changed

README.md

Lines changed: 105 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,31 @@ A lightweight, robust, flexible, and containerized NFS server.
77
This is the only containerized NFS server that offers **all** of the following features:
88

99
- NFS versions 3, 4, or both simultaneously
10-
- optional Kerberos security
11-
- optional name/ID mapping via [`idmapd`](http://man7.org/linux/man-pages/man8/idmapd.8.html)
12-
- clean teardown of services upon `SIGTERM` or `SIGKILL` (no lingering `nfsd` processes on Docker host)
13-
- flexible construction of `/etc/exports` via a Docker bind mount *or* environment variables
10+
- clean teardown of services upon termination (no lingering `nfsd` processes on Docker host)
11+
- flexible construction of `/etc/exports`
1412
- extensive server configuration via environment variables
13+
- *optional* bonus features
14+
- [Kerberos security](docs/feature/kerberos.md)
15+
- [NFSv4 user ID mapping](docs/feature/nfs4-user-id-mapping.md) via [`idmapd`](http://man7.org/linux/man-pages/man8/idmapd.8.html)
16+
- [AppArmor](docs/feature/apparmor.md) compatibility
17+
18+
## Table of Contents
19+
20+
* [Requirements](#requirements)
21+
* Usage
22+
* [Starting the server](#starting-the-server)
23+
* [Mounting filesystems from a client](#mounting-filesystems-from-a-client)
24+
* Optional features
25+
* [Kerberos security](docs/feature/kerberos.md)
26+
* [NFSv4 user ID mapping](docs/feature/nfsv4-user-id-mapping.md)
27+
* [AppArmor integration](docs/feature/apparmor.md)
28+
* Advanced
29+
* [custom server ports](docs/advanced/ports.md)
30+
* [custom NFS versions offered](docs/advanced/nfs-versions.md)
31+
* [performance tuning](docs/advanced/performance-tuning.md)
32+
* [Help!](#help!)
33+
* [Remaining tasks](#remaining-tasks)
34+
* [Acknowledgements](#acknowledgements)
1535

1636
## Requirements
1737

@@ -22,150 +42,118 @@ This is the only containerized NFS server that offers **all** of the following f
2242

2343
Usually you can enable these modules with: `modprobe {nfs,nfsd,rpcsec_gss_krb5}`
2444
1. 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.
25-
1. 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.
26-
27-
- `-v some_volume:/some/container/path` (Docker volume)
28-
- `-v /some/path/on/host:/some/container/path` (bind mount)
29-
- `ADD /some/path/on/host /some/container/path` (Dockerfile)
45+
1. The container will need local access to the files you'd like to serve via NFS. You can use Docker volumes, bind mounts, files baked into a custom image, or virtually any other means of supplying files to a Docker container.
3046

3147
## Usage
3248

33-
### Hello, World!
34-
35-
You will need to provide your desired [NFS exports](https://linux.die.net/man/5/exports) (`/etc/exports`) upon container startup. You have **three choices** for doing this:
36-
37-
1. **Bind mount `/etc/exports` into the container**
49+
### Starting the server
3850

39-
docker run \
40-
-v /host/path/to/exports.txt:/etc/exports:ro \
41-
-v /host/files:/nfs \
42-
--cap-add SYS_ADMIN \
43-
-p 2049:2049 \
44-
erichough/nfs-server
45-
46-
1. **Provide each line of `/etc/exports` as an environment variable**
51+
Starting the `erichough/nfs-server` image will launch an NFS server. You'll need to supply some information upon container startup, which we'll cover below, but briefly speaking your `docker run` command might look something like this:
4752

48-
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.
53+
docker run \
54+
-v /host/path/to/shared/files:/nfs \
55+
-v /host/path/to/exports.txt:/etc/exports:ro \
56+
--cap-add SYS_ADMIN \
57+
-p 2049:2049 \
58+
erichough/nfs-server
59+
60+
Let's break that command down into its individual pieces to see what's required for a successful server startup.
4961

50-
docker run \
51-
-e NFS_EXPORT_0='/nfs/foo 192.168.1.0/24(ro,no_subtree_check)' \
52-
-e NFS_EXPORT_1='/nfs/bar 123.123.123.123/32(rw,no_subtree_check)' \
53-
-v /host/path/foo:/nfs/foo \
54-
-v /host/path/bar:/nfs/bar \
55-
--cap-add SYS_ADMIN \
56-
-p 2049:2049 \
57-
erichough/nfs-server
62+
1. **Provide the files to be shared over NFS**
5863

59-
1. **Bake `/etc/exports` into a custom image**
64+
As noted in the [requirements](#requirements), the container will need local access to the files you'd like to share over NFS. Some ideas for supplying these files:
65+
66+
* [bind mounts](https://docs.docker.com/storage/bind-mounts/) (`-v /host/path/to/shared/files:/nfs`)
67+
* [volumes](https://docs.docker.com/storage/volumes/) (`-v some_volume:/nfs`)
68+
* files [baked into](https://docs.docker.com/engine/reference/builder/#copy) custom image (e.g. in a `Dockerfile`: `COPY /host/files /nfs`)
6069

61-
e.g. in a `Dockerfile`:
70+
You may use any combination of the above, or any other means to supply files to the container.
6271

63-
FROM ehough/nfs-server
64-
ADD /host/path/to/exports.txt /etc/exports
72+
1. **Provide your desired [NFS exports](https://linux.die.net/man/5/exports) (`/etc/exports`)**
6573

66-
### (Optional) NFSv4 User ID Mapping
74+
You'll need to tell the server which container directories to export. You have *three options* for this; choose whichever one you prefer:
6775

68-
If you'd like to run [`idmapd`](http://man7.org/linux/man-pages/man8/idmapd.8.html) to map between NFSv4 IDs (e.g. `[email protected]`) and local users, simply provide [`idmapd.conf`](https://linux.die.net/man/5/idmapd.conf) and `/etc/passwd` to the container. This step is required for Kerberos.
76+
1. bind mount `/etc/exports` into the container
6977

70-
docker run \
71-
-v /host/path/to/exports.txt:/etc/exports:ro \
72-
-v /host/files:/nfs \
73-
-v /host/path/to/idmapd.conf:/etc/idmapd.conf:ro \
74-
-v /etc/passwd:/etc/passwd:ro \
75-
--cap-add SYS_ADMIN \
76-
-p 2049:2049 \
77-
erichough/nfs-server
78+
docker run \
79+
-v /host/path/to/exports.txt:/etc/exports:ro \
80+
... \
81+
erichough/nfs-server
7882
79-
### (Optional) Kerberos
80-
81-
You can enable Kerberos security by performing the following additional actions:
82-
83-
1. set the environment variable `NFS_ENABLE_KERBEROS` to a non-empty value (e.g. `NFS_ENABLE_KERBEROS=1`)
84-
1. set the server's hostname via the `--hostname` flag
85-
1. provide `/etc/krb5.keytab` which contains a principal of the form `nfs/<hostname>`, where `<hostname>` is the hostname you supplied in the previous step.
86-
1. provide [`/etc/krb5.conf`](https://web.mit.edu/kerberos/krb5-1.12/doc/admin/conf_files/krb5_conf.html)
87-
1. provide [`/etc/idmapd.conf`](https://linux.die.net/man/5/idmapd.conf)
88-
1. provide `/etc/passwd` containing your NFS client users
89-
90-
Here's an example:
91-
92-
docker run \
93-
-v /host/path/to/exports.txt:/etc/exports:ro \
94-
-v /host/files:/nfs \
95-
-e NFS_ENABLE_KERBEROS=1 \
96-
--hostname my-nfs-server.com \
97-
-v /host/path/to/server.keytab:/etc/krb5.keytab:ro \
98-
-v /host/path/to/server.krb5conf:/etc/krb5.conf:ro \
99-
-v /host/path/to/idmapd.conf:/etc/idmapd.conf:ro \
100-
-v /etc/passwd:/etc/passwd:ro \
101-
--cap-add SYS_ADMIN \
102-
-p 2049:2049 \
103-
erichough/nfs-server
104-
105-
### Environment Variables
106-
107-
The following optional environment variables allow you to adjust the server settings to your needs.
108-
109-
- **`NFS_VERSION`** (default is `4.2`)
110-
111-
Set to `3`, `4`, `4.1`, or `4.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.
83+
1. provide each line of `/etc/exports` as an environment variable
11284

113-
- **`NFS_DISABLE_VERSION_3`** (*not set by default*)
85+
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.
11486

115-
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 with `NFS_VERSION=3`.
87+
docker run \
88+
-e NFS_EXPORT_0='/nfs/foo *(ro,no_subtree_check)' \
89+
-e NFS_EXPORT_1='/nfs/bar 123.123.123.123/32(rw,no_subtree_check)' \
90+
... \
91+
erichough/nfs-server
11692

117-
- **`NFS_PORT`** (default is `2049`)
93+
1. bake `/etc/exports` into a custom image
11894

119-
Set this to any valid port number (`1` - `65535` inclusive) to change `rpc.nfsd`'s listening port.
95+
e.g. in a `Dockerfile`:
12096

121-
- **`NFS_SERVER_THREAD_COUNT`** (default is *CPU core count*)
97+
FROM ehough/nfs-server
98+
ADD /host/path/to/exports.txt /etc/exports
12299

123-
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.
100+
1. **Use `--cap-add SYS_ADMIN` or `--privileged`**
124101

125-
- **`NFS_PORT_MOUNTD`** (default is `32767`)
126-
127-
*Only needed for NFS 3*. Set this to any valid port number (`1` - `65535` inclusive) to change `rpc.mountd`'s listening port.
128-
129-
- **`NFS_PORT_STATD_IN`** (default is `32765`)
130-
131-
*Only needed for NFS 3*. Set this to any valid port number (`1` - `65535` inclusive) to change `rpc.statd`'s listening port.
132-
133-
- **`NFS_PORT_STATD_OUT`** (default is `32766`)
134-
135-
*Only needed for NFS 3*. Set this to any valid port number (`1` - `65535` inclusive) to change `rpc.statd`'s outgoing connection port.
136-
137-
- **`NFS_ENABLE_KERBEROS`** (*not set by default*)
102+
As noted in the [requirements](#requirements), the container will need additional privileges. So your `run` command will need either:
103+
104+
docker run --cap-add SYS_ADMIN ... erichough/nfs-server
105+
106+
or
107+
108+
docker run --privileged ... erichough/nfs-server
109+
110+
Not sure which to use? Go for `--cap-add SYS_ADMIN` as it's the lesser of two evils.
111+
112+
1. **Expose the server ports**
113+
114+
You'll need to open up at least one server port for your client connections. The ports listed in the examples below are the defaults used by this image and most can be [customized](docs/ports.md).
115+
116+
* If your clients connect via **NFSv4 only**, you can get by with just TCP port `2049`:
117+
118+
docker run -p 2049:2049 ... erichough/nfs-server
119+
120+
* If you need to support **NFSv3**, you'll need to expose a lot more ports:
121+
122+
docker run \
123+
-p 2049:2049 -p 2049:2049/udp \
124+
-p 111:111 -p 111:111/udp \
125+
-p 32765:32765 -p 32765:32765/udp \
126+
-p 32767:32767 -p 32767:32767/udp \
127+
... \
128+
erichough/nfs-server
129+
130+
If you pay close attention to each of the items in this section, the server should start quickly and be ready to accept your NFS clients.
131+
132+
### Mounting filesystems from a client
138133

139-
Set to a non-empty value (e.g. `NFS_ENABLE_KERBEROS=1`) to enable Kerberos on this server. See the [Kerberos](#kerberos) section above for further details.
134+
# mount <container-IP>:/some/export /some/local/path
140135

141-
### Which ports need to be exposed?
136+
## Optional Features
142137

143-
* NFSv4
144-
* `2049`
145-
* NFSv3
146-
* `111` & `111/udp`
147-
* `2049` & `2049/udp`
148-
* `32765` & `32765/udp`
149-
* `32767` & `32767/udp`
138+
* [Kerberos security](docs/feature/kerberos.md)
139+
* [NFSv4 user ID mapping](docs/feature/nfsv4-user-id-mapping.md)
140+
* [AppArmor integration](docs/feature/apparmor.md)
150141

151-
These ports can be exposed using the usual [Docker syntax](https://docs.docker.com/engine/reference/run/#expose-incoming-ports) (e.g. `-p 2049:2049`), and most can be customized via [environment variables](#environment-variables).
152-
153-
### Mounting filesystems from a client
154-
155-
# mount -o nfsvers=4 <container-IP>:/some/export /some/local/path
156-
157-
### Connecting to the running container
142+
## Advanced
158143

159-
# docker exec -it <container-id> bash
144+
* [customizing which ports are used](docs/advanced/ports.md)
145+
* [customizing NFS versions offered](docs/advanced/nfs-versions.md)
146+
* [performance tuning](docs/advanced/performance-tuning.md)
160147

161-
## Performance considerations
148+
## Help!
162149

163-
- Running the container with `--network host` *might* improve network performance by 10% - 20% [[1](https://jtway.co/docker-network-performance-b95bce32b4b9),[2](https://www.percona.com/blog/2016/08/03/testing-docker-multi-host-network-performance/)], though this hasn't been tested.
150+
Please [open an issue](https://github.com/ehough/docker-nfs-server/issues) if you have any questions, constructive criticism, or can't get something to work.
164151

165152
## Remaining tasks
166153

167-
- switch back to Alpine Linux once [this bug](https://bugs.alpinelinux.org/issues/8470) in `nfs-utils` is fixed
154+
- switch to Alpine Linux once [this bug](https://bugs.alpinelinux.org/issues/8470) in `nfs-utils` is fixed
168155
- figure out why `rpc.nfsd` takes 5 minutes to startup/timeout unless `rpcbind` is running
156+
- add more examples, including Docker Compose
169157

170158
## Acknowledgements
171159

doc/advanced/nfs-versions.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Customize NFS versions offered
2+
3+
By default, this image provides NFS versions 3 and 4 simultaneously. Using the following environment variables, you can fine-tune which versions are offered.
4+
5+
| Environment variable | Description | Default |
6+
|-------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|
7+
| `NFS_VERSION` | Set to `3`, `4`, `4.1`, or `4.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. | `4.2` |
8+
| `NFS_DISABLE_VERSION_3` | 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 with `NFS_VERSION=3` | *not set* |

doc/advanced/performance-tuning.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Performance tuning
2+
3+
The following tips might improve your NFS server's performance.
4+
5+
* Set the **`NFS_SERVER_THREAD_COUNT`** environment variable 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. The default is one thread per CPU core.
6+
7+
* Running the container with `--network host` *might* improve network performance by 10% - 20% [[1](https://jtway.co/docker-network-performance-b95bce32b4b9),[2](https://www.percona.com/blog/2016/08/03/testing-docker-multi-host-network-performance/)], though this hasn't been tested.

doc/advanced/ports.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Customizing ports
2+
3+
You can customize the ports used by the NFS server via the environment variables listed below. Each environment variable can be set to an integer between `1` and `65535`.
4+
5+
| Environment variable | Description | Default |
6+
|----------------------|---------------------------------------------|---------|
7+
| `NFS_PORT` | `rpc.nfsd`'s listening port. | `2049` |
8+
| `NFS_PORT_MOUNTD` | *NFSv3 only*. `rpc.mountd'` listening port. | `32767` |
9+
| `NFS_PORT_STATD_IN` | *NFSv3 only*. `rpc.statd`'s listening port. | `32765` |
10+
| `NFS_PORT_STATD_OUT` | *NFSv3 only*. `rpc.statd`'s outgoing port. | `32766` |

doc/feature/apparmor.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# AppArmor
2+
3+
If your Docker host has [AppArmor](https://wiki.ubuntu.com/AppArmor) activated, you'll need to perform additional steps to allow the container to start an NFS server.
4+
5+
1. Ensure you have the `apparmor-utils` installed package installed on the Docker host. e.g. for Debian:
6+
7+
$ sudo apt-get install apparmor-utils
8+
9+
1. Create a file on the Docker host with the following contents:
10+
11+
#include <tunables/global>
12+
profile erichough-nfs flags=(attach_disconnected,mediate_deleted) {
13+
#include <abstractions/lxc/container-base>
14+
mount fstype=nfs*,
15+
mount fstype=rpc_pipefs,
16+
}
17+
18+
1. Load this profile into AppArmor:
19+
20+
$ sudo apparmor_parser -r -W /path/to/file/from/previous/step
21+
22+
1. Add `--security-opt apparmor=erichough-nfs` to your `docker run` command. e.g.
23+
24+
docker run \
25+
-v /path/to/exports.txt:/etc/exports:ro \
26+
-v /path/to/share:/nfs \
27+
--cap-add SYS_ADMIN \
28+
-p 2049:2049 \
29+
--security-opt apparmor=erichough-nfs \
30+
erichough/nfs-server

doc/feature/kerberos.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Kerberos
2+
3+
You can enable Kerberos security for your NFS server with the following steps.
4+
5+
1. set the environment variable `NFS_ENABLE_KERBEROS` to a non-empty value (e.g. `NFS_ENABLE_KERBEROS=1`)
6+
1. set the server's hostname via the `--hostname` flag
7+
1. provide `/etc/krb5.keytab` which contains a principal of the form `nfs/<hostname>`, where `<hostname>` is the hostname you supplied in the previous step.
8+
1. provide [`/etc/krb5.conf`](https://web.mit.edu/kerberos/krb5-1.12/doc/admin/conf_files/krb5_conf.html)
9+
1. provide [`/etc/idmapd.conf`](https://linux.die.net/man/5/idmapd.conf)
10+
1. provide `/etc/passwd` containing your NFS client users
11+
12+
Here's an example:
13+
14+
docker run \
15+
-v /host/path/to/exports.txt:/etc/exports:ro \
16+
-v /host/files:/nfs \
17+
-e NFS_ENABLE_KERBEROS=1 \
18+
--hostname my-nfs-server.com \
19+
-v /host/path/to/server.keytab:/etc/krb5.keytab:ro \
20+
-v /host/path/to/server.krb5conf:/etc/krb5.conf:ro \
21+
-v /host/path/to/idmapd.conf:/etc/idmapd.conf:ro \
22+
-v /etc/passwd:/etc/passwd:ro \
23+
--cap-add SYS_ADMIN \
24+
-p 2049:2049 \
25+
erichough/nfs-server

doc/feature/nfs4-user-id-mapping.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# NFSv4 User ID Mapping
2+
3+
If you'd like to run [`idmapd`](http://man7.org/linux/man-pages/man8/idmapd.8.html) to map between NFSv4 IDs (e.g. `[email protected]`) and local users, simply provide [`idmapd.conf`](https://linux.die.net/man/5/idmapd.conf) and `/etc/passwd` to the container. This step is required for [Kerberos](kerberos.md).
4+
5+
docker run \
6+
-v /host/path/to/exports.txt:/etc/exports:ro \
7+
-v /host/files:/nfs \
8+
-v /host/path/to/idmapd.conf:/etc/idmapd.conf:ro \
9+
-v /etc/passwd:/etc/passwd:ro \
10+
--cap-add SYS_ADMIN \
11+
-p 2049:2049 \
12+
erichough/nfs-server
13+

0 commit comments

Comments
 (0)