{"id":16532823,"url":"https://github.com/mjstealey/nfs-in-docker","last_synced_at":"2025-10-28T11:31:29.564Z","repository":{"id":93420578,"uuid":"133994514","full_name":"mjstealey/nfs-in-docker","owner":"mjstealey","description":"NFS version 3 server and client in docker","archived":false,"fork":false,"pushed_at":"2018-05-18T19:21:46.000Z","size":10,"stargazers_count":8,"open_issues_count":1,"forks_count":10,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-01T14:51:10.295Z","etag":null,"topics":["centos-7","docker","nfs","nfs-client","nfs-server"],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mjstealey.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-05-18T19:11:50.000Z","updated_at":"2024-07-23T06:34:50.000Z","dependencies_parsed_at":"2023-08-25T19:05:13.473Z","dependency_job_id":null,"html_url":"https://github.com/mjstealey/nfs-in-docker","commit_stats":{"total_commits":3,"total_committers":1,"mean_commits":3.0,"dds":0.0,"last_synced_commit":"c9a0aa740f0b41b1b425843b5fc0d8e702f25bd7"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mjstealey%2Fnfs-in-docker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mjstealey%2Fnfs-in-docker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mjstealey%2Fnfs-in-docker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mjstealey%2Fnfs-in-docker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mjstealey","download_url":"https://codeload.github.com/mjstealey/nfs-in-docker/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238645714,"owners_count":19506898,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["centos-7","docker","nfs","nfs-client","nfs-server"],"created_at":"2024-10-11T18:13:30.807Z","updated_at":"2025-10-28T11:31:24.278Z","avatar_url":"https://github.com/mjstealey.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NFS in Docker\n\n**WORK IN PROGRESS**\n\nNFS version 3 server and client in docker.\n\n## About\n\nDefinitions for both an NFS server and client have been defined using CentOS 7 as the base. Using docker-compose to coordinate two node demonstration.\n\nVolumes served by the NFS server can be defined as host volume mounts, or reside strictly inside the docker container. Volumes are mounted at runtime based on environment variables passed into the container.\n\n## Environment variables\n\n### Server\n\n### `RPCNFSDCOUNT`\n\nnfsd threads - number of nfsd threads to use. Default `=8`.\n\n### `NFS_SERVER_DIRS`\n\nNSF mounts - full path for server side NFS volumes, as seen by the container, that will be serviced. Default `='/nfs/share'`. All volumes should begin with `/nfs` and a semicolon (`:`) should be used between each path definition.\n\n### Client\n\n### `NFS_SERVER`\n\nFQDN or IP - of the NFS server. Default `=server`.\n\n### `NFS_SERVER_DIRS`\n\nVolumes as provided from the NFS server. Default `='/nfs/share'`.\n\n### `NFS_CLIENT_DIRS`\n\nVolumes to mount on the client. Default `='/mnt/share'`. Must be an in order correlation to the volumes as defined in `NFS_SERVER_DIRS` as that is the order they will be mounted in. Example: `mount ${NFS_SERVER}:${NFS_SERVER_DIRS[0]} ${NFS_CLIENT_DIRS[0]}`\n\n## Preliminary setup\n\n### docker volume\n\nDue to differences in permissions in how macOS and Linux treat host mounted volumes, a docker volume will be defined for use by the primary NFS export directory, and bound to the server container.\n\n### Linux\n\nCreate directory named **nfs** and create a docker volume with it:\n\n```\nmkdir nfs\ndocker volume create \\\n  --name nfs \\\n  --opt type=tmpfs \\\n  --opt device=$(pwd)/nfs \\\n  --opt o=bind\n```\n\nVerify creation of volume:\n\n```console\n$ docker volume inspect nfs\n[\n    {\n        \"CreatedAt\": \"2018-05-18T13:37:27-04:00\",\n        \"Driver\": \"local\",\n        \"Labels\": {},\n        \"Mountpoint\": \"/var/lib/docker/volumes/nfs/_data\",\n        \"Name\": \"nfs\",\n        \"Options\": {\n            \"device\": \"/home/$USER/nfs-in-docker/nfs\",\n            \"o\": \"bind\",\n            \"type\": \"tmpfs\"\n        },\n        \"Scope\": \"local\"\n    }\n]\n```\n\nViewing the contents of the volume: Since the Linux volume is bound to the host, we can simply observe the contents using `ls`.\n\n```\nls -lR nfs\n```\n\n### macOS\n\nCreate docker volume named **nfs**:\n\n```\ndocker volume create \\\n  --name nfs \\\n  --driver local \\\n  --opt type=tmpfs \\\n  --opt device=tmpfs\n```\n\nVerify creation of volume:\n\n```console\n$ docker volume inspect nfs\n[\n    {\n        \"CreatedAt\": \"2018-05-18T16:09:05Z\",\n        \"Driver\": \"local\",\n        \"Labels\": {},\n        \"Mountpoint\": \"/var/lib/docker/volumes/nfs/_data\",\n        \"Name\": \"nfs\",\n        \"Options\": {\n            \"device\": \"tmpfs\",\n            \"type\": \"tmpfs\"\n        },\n        \"Scope\": \"local\"\n    }\n]\n```\n\nViewing the contents of the volume: Run this from your Mac terminal and it'll drop you in a container with full permissions on the Moby VM. This also works for Docker for Windows for getting in Moby Linux VM (doesn't work for Windows Containers).\n\n```\ndocker run -it --rm --privileged --pid=host justincormack/nsenter1\n```\n\nList docker's volumes\n\n```\nls /var/lib/docker/volumes\n```\n\nmore info: [https://github.com/justincormack/nsenter1](https://github.com/justincormack/nsenter1)\n\n## Start the `docker-compose.yml` file\n\nA [docker-compose.yml](docker-compose.yml) file has been provided to create the two node server and client network for demonstration.\n\n```console\n$ docker-compose up -d\nCreating client ... done\nCreating server ... done\n```\n\nOnce run the user should observe two new containers\n\n```console\n$ docker-compose ps\n Name               Command               State         Ports\n-------------------------------------------------------------------\nclient   /usr/local/bin/tini -- /do ...   Up\nserver   /usr/local/bin/tini -- /do ...   Up      111/udp, 2049/tcp\n```\n\nAt this point the NFS server container should be serving four directories to the NFS client container.\n\nFrom the `server`:\n\n```console\n$ docker exec server cat /etc/exports\n/nfs/secret *(rw,sync,no_subtree_check,no_root_squash,fsid=272)\n/nfs/home *(rw,sync,no_subtree_check,no_root_squash,fsid=281)\n/nfs/modules *(rw,sync,no_subtree_check,no_root_squash,fsid=238)\n/nfs/modulefiles *(rw,sync,no_subtree_check,no_root_squash,fsid=250)\n```\n\n\nFrom the `client`:\n\n```console\n$ docker exec client showmount -e server\nExport list for server:\n/nfs/modulefiles *\n/nfs/modules     *\n/nfs/home        *\n/nfs/secret      *\n$ docker exec client cat /etc/fstab\n### \u003cserver\u003e:\u003c/remote/export\u003e \u003c/local/directory\u003e \u003cnfs-type\u003e \u003coptions\u003e 0 0\nserver:/nfs/secret /secret nfs rw,hard,intr 0 0\nserver:/nfs/home /home nfs rw,hard,intr 0 0\nserver:/nfs/modules /opt/apps/Linux nfs rw,hard,intr 0 0\nserver:/nfs/modulefiles /opt/apps/modulefiles/Linux nfs rw,hard,intr 0 0\n```\n\nThe directories should all initially be empty (example using Linux volume mount).\n\n```console\n$ ls -lR nfs\nnfs:\ntotal 0\ndrwxrwxrwx 2 root root 6 May 18 13:37 home\ndrwxrwxrwx 2 root root 6 May 18 13:37 modulefiles\ndrwxrwxrwx 2 root root 6 May 18 13:37 modules\ndrwxrwxrwx 2 root root 6 May 18 13:37 secret\n\nnfs/home:\ntotal 0\n\nnfs/modulefiles:\ntotal 0\n\nnfs/modules:\ntotal 0\n\nnfs/secret:\ntotal 0\n```\n\n## Test with `nfs-test.sh`\n\nA script named [nfs-test.sh](nfs-test.sh) has been provided to test the NFS mounts.\n\nRun `$ ./nfs-test.sh`, the following output should be observed:\n\n```console\n### NFS test ###\n\n### write on server ###\n$ touch /nfs/home/server-touch-home\n$ touch /nfs/secret/server-touch-secret\n$ touch /nfs/modules/server-touch-modules\n$ touch /nfs/modulefiles/server-touch-modulefiles\n\n### read from client ###\n$ ls -l /home\ntotal 0\n-rw-r--r-- 1 root root 0 May 18 17:45 server-touch-home\n$ ls -l /secret\ntotal 0\n-rw-r--r-- 1 root root 0 May 18 17:45 server-touch-secret\n$ ls -l /opt/apps/Linux\ntotal 0\n-rw-r--r-- 1 root root 0 May 18 17:45 server-touch-modules\n$ ls -l /opt/apps/modulefiles/Linux\ntotal 0\n-rw-r--r-- 1 root root 0 May 18 17:45 server-touch-modulefiles\n\n### write on client ###\n$ touch /home/client-touch-home\n$ touch /secret/client-touch-secret\n$ touch /opt/apps/Linux/client-touch-modules\n$ touch /opt/apps/modulefiles/Linux/client-touch-modulefiles\n\n### read from server ###\n$ ls -l /nfs/home\ntotal 0\n-rw-r--r-- 1 root root 0 May 18 17:45 client-touch-home\n-rw-r--r-- 1 root root 0 May 18 17:45 server-touch-home\n$ ls -l /nfs/secret\ntotal 0\n-rw-r--r-- 1 root root 0 May 18 17:45 client-touch-secret\n-rw-r--r-- 1 root root 0 May 18 17:45 server-touch-secret\n$ ls -l /nfs/modules\ntotal 0\n-rw-r--r-- 1 root root 0 May 18 17:45 client-touch-modules\n-rw-r--r-- 1 root root 0 May 18 17:45 server-touch-modules\n$ ls -l /nfs/modulefiles\ntotal 0\n-rw-r--r-- 1 root root 0 May 18 17:45 client-touch-modulefiles\n-rw-r--r-- 1 root root 0 May 18 17:45 server-touch-modulefiles\n\n### create user=worker, gid=1000, uid=1000 from client ###\n$ groupadd --gid 1000 worker \u0026\u0026 useradd  -m -c \"Workflow user\" -d /home/worker --uid 1000 -g worker  -s /bin/bash worker\n\n### read from client ###\n$ ls -l /home\ntotal 0\n-rw-r--r-- 1 root   root    0 May 18 17:45 client-touch-home\n-rw-r--r-- 1 root   root    0 May 18 17:45 server-touch-home\ndrwx------ 2 worker worker 59 May 18 17:45 worker\n\n### read from server ###\n$ ls -l /nfs/home\ntotal 0\n-rw-r--r-- 1 root root  0 May 18 17:45 client-touch-home\n-rw-r--r-- 1 root root  0 May 18 17:45 server-touch-home\ndrwx------ 2 1000 1000 59 May 18 17:45 worker\n```\n\nThe directories of the `nfs` volume should now be populated (example using Linux volume mount).\n\n```console\n$ ls -lR nfs\nnfs:\ntotal 0\ndrwxrwxrwx 3 root root 67 May 18 13:45 home\ndrwxrwxrwx 2 root root 68 May 18 13:45 modulefiles\ndrwxrwxrwx 2 root root 60 May 18 13:45 modules\ndrwxrwxrwx 2 root root 58 May 18 13:45 secret\n\nnfs/home:\ntotal 0\n-rw-r--r-- 1 root    root   0 May 18 13:45 client-touch-home\n-rw-r--r-- 1 root    root   0 May 18 13:45 server-touch-home\ndrwx------ 2 1000    1000  59 May 18 13:45 worker\nls: cannot open directory nfs/home/worker: Permission denied\n\nnfs/modulefiles:\ntotal 0\n-rw-r--r-- 1 root root 0 May 18 13:45 client-touch-modulefiles\n-rw-r--r-- 1 root root 0 May 18 13:45 server-touch-modulefiles\n\nnfs/modules:\ntotal 0\n-rw-r--r-- 1 root root 0 May 18 13:45 client-touch-modules\n-rw-r--r-- 1 root root 0 May 18 13:45 server-touch-modules\n\nnfs/secret:\ntotal 0\n-rw-r--r-- 1 root root 0 May 18 13:45 client-touch-secret\n-rw-r--r-- 1 root root 0 May 18 13:45 server-touch-secret\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmjstealey%2Fnfs-in-docker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmjstealey%2Fnfs-in-docker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmjstealey%2Fnfs-in-docker/lists"}