# Mount external NFS ( or local filesystem )

**URL:** <https://discourse.jupyter.org/t/mount-external-nfs-or-local-filesystem/6139>\
**Category:** Zero to JupyterHub on Kubernetes\
**Tags:** help-wanted\
**Created:** [September 25, 2020, 2:54pm UTC](https://discourse.jupyter.org/t/mount-external-nfs-or-local-filesystem/6139 "2020-09-25T14:54:24Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![moscardo](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/moscardo/32/1307_2.png) [@moscardo](https://discourse.jupyter.org/u/moscardo)\
**Post date:** [September 25, 2020, 2:54pm UTC](https://discourse.jupyter.org/t/mount-external-nfs-or-local-filesystem/6139/1 "2020-09-25T14:54:24Z")

</div>

Hi,  
We have manage to configure z2jh to spin up containers ran by specific UID/GID from our LDAP, but now we need those containers to be able to mount an NFS mount from outside of k8s, or we can also mount that NFS on each host from the k8s cluster and then mount local paths into the containers. Is that possible with z2jh ?

Cheers.

---

<div class="post-metadata">

**Author:** ![manics](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/manics/32/85_2.png) [@manics](https://discourse.jupyter.org/u/manics)\
**Post date:** [September 25, 2020, 10:06pm UTC](https://discourse.jupyter.org/t/mount-external-nfs-or-local-filesystem/6139/2 "2020-09-25T22:06:17Z")

</div>

If you can make your external mounts appear as a Kubernetes PVC you can mount them into your user containers with Z2JH:

> **[Customizing User Storage — Zero to JupyterHub with Kubernetes...](https://zero-to-jupyterhub.readthedocs.io/en/latest/customizing/user-storage.html#additional-storage-volumes)**

---

<div class="post-metadata">

**Author:** ![moscardo](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/moscardo/32/1307_2.png) [@moscardo](https://discourse.jupyter.org/u/moscardo)\
**Post date:** [September 25, 2020, 10:25pm UTC](https://discourse.jupyter.org/t/mount-external-nfs-or-local-filesystem/6139/3 "2020-09-25T22:25:01Z")

</div>

Hi @manics,  
How would I do that? Is it something I can do from k8s? Do you have any docu?

Thanks.

---

<div class="post-metadata">

**Author:** ![manics](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/manics/32/85_2.png) [@manics](https://discourse.jupyter.org/u/manics)\
**Post date:** [September 26, 2020, 9:06am UTC](https://discourse.jupyter.org/t/mount-external-nfs-or-local-filesystem/6139/4 "2020-09-26T09:06:13Z")

</div>

Yes, you could create it manually in K8S, then add it to your Z2JH config.

> **[Persistent Volumes](https://kubernetes.io/docs/concepts/storage/persistent-volumes/)**
>
> This document describes the current state of persistent volumes in Kubernetes. Familiarity with volumes is suggested.
> Introduction Managing storage is a distinct problem from managing compute instances. The PersistentVolume subsystem provides an API...

---

<div class="post-metadata">

**Author:** ![moscardo](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/moscardo/32/1307_2.png) [@moscardo](https://discourse.jupyter.org/u/moscardo)\
**Post date:** [September 28, 2020, 2:21pm UTC](https://discourse.jupyter.org/t/mount-external-nfs-or-local-filesystem/6139/5 "2020-09-28T14:21:26Z")

</div>

Hi @manics have created PV and PVC and it works fine, but when I try to mount it under /home, the spawn of the singleuser container fails due to impossibility of creation of /home/jovyan

```auto
2020-09-28 13:56:58+00:00 [Warning] Error: failed to start container "notebook": Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "process_linux.go:449: container init caused \"mkdir /home/jovyan: permission denied\"": unknown

```

I am not sure at which point it is trying to create default user’s home, the helm chart looks like:

```auto
  extraEnv:
    CHOWN_HOME: 'yes'
  uid: 0
  fsGid: 0
  serviceAccountName:
  storage:
    type: static
    extraLabels: {}
    static:
      pvcName: pvc-nfs-home
      subPath: 'home/{username}'
    capacity: 10Gi
    homeMountPath: /home

```

---

<div class="post-metadata">

**Author:** ![manics](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/manics/32/85_2.png) [@manics](https://discourse.jupyter.org/u/manics)\
**Post date:** [September 28, 2020, 6:12pm UTC](https://discourse.jupyter.org/t/mount-external-nfs-or-local-filesystem/6139/6 "2020-09-28T18:12:51Z")

</div>

Is your Dockerfile publicly available?

---

<div class="post-metadata">

**Author:** ![moscardo](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/moscardo/32/1307_2.png) [@moscardo](https://discourse.jupyter.org/u/moscardo)\
**Post date:** [September 28, 2020, 6:18pm UTC](https://discourse.jupyter.org/t/mount-external-nfs-or-local-filesystem/6139/7 "2020-09-28T18:18:29Z")

</div>

that is basically my Dockerfile

```auto
20:16 # cat /root/test-nb/datascience-notebook/Dockerfile 
FROM jupyter/datascience-notebook:latest
USER root
ADD ./passwd /etc/passwd
ADD ./group /etc/group
USER $NB_UID

```

---

<div class="post-metadata">

**Author:** ![moscardo](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/moscardo/32/1307_2.png) [@moscardo](https://discourse.jupyter.org/u/moscardo)\
**Post date:** [September 28, 2020, 6:48pm UTC](https://discourse.jupyter.org/t/mount-external-nfs-or-local-filesystem/6139/8 "2020-09-28T18:48:15Z")

</div>

it was a typo…sorry. Now I can mount it in /home/{username} and $HOME is properly set up, but still /home/jovyan is what you see when you open a terminal. the if you do :  
cd $HOME

you get to your home.  
 ![image](https://canada1.discourse-cdn.com/flex031/uploads/jupyter/original/2X/f/f06fbb5087be1b8f579a91c86596f40dfdc543d7.png)

---

<div class="post-metadata">

**Author:** ![manics](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/manics/32/85_2.png) [@manics](https://discourse.jupyter.org/u/manics)\
**Post date:** [September 29, 2020, 6:49pm UTC](https://discourse.jupyter.org/t/mount-external-nfs-or-local-filesystem/6139/9 "2020-09-29T18:49:02Z")

</div>

Kubespawner has a `working_dir` config option

> <https://github.com/jupyterhub/kubespawner/blob/3639767f5295e8ac97ff41910bdf9ee8a589278a/kubespawner/spawner.py#L305-L315>

But this isn’t exposed in Z2JH. You should however be able to set it using [`hub.extraConfig`](https://zero-to-jupyterhub.readthedocs.io/en/latest/administrator/advanced.html#hub-extraconfig). Try something like

```auto
hub:
  extraConfig: |
    c.KubeSpawner.working_dir = '/home/{username}'

```

---

<div class="post-metadata">

**Author:** ![moscardo](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/moscardo/32/1307_2.png) [@moscardo](https://discourse.jupyter.org/u/moscardo)\
**Post date:** [September 30, 2020, 9:31am UTC](https://discourse.jupyter.org/t/mount-external-nfs-or-local-filesystem/6139/10 "2020-09-30T09:31:56Z")

</div>

It seems that if I set it to:

```auto
 c.KubeSpawner.working_dir = '/home'

```

it works, but when adding `{username}` I get :

```auto
Error: failed to start container "notebook": Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "chdir to cwd (\"/home/moscardo\") set in config.json failed: permission denied": unknown

```

Is it maybe because it is trying to set the working directory as root and because NFS is no\_root\_squash it needs to be the user? Or maybe because the share is still not mounted at this point?

---

<div class="post-metadata">

**Author:** ![manics](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/manics/32/85_2.png) [@manics](https://discourse.jupyter.org/u/manics)\
**Post date:** [September 30, 2020, 12:23pm UTC](https://discourse.jupyter.org/t/mount-external-nfs-or-local-filesystem/6139/11 "2020-09-30T12:23:51Z")

</div>

The share should be mounted before the pod starts. It’s possible your NFS server restricts the chown operation or imposes some other restrictions. Can you try running `chmod` on the NFS server to change the UID of the directory to your user, and remove `CHOWN_HOME: 'yes'` from your Z2JH config?

---

<div class="post-metadata">

**Author:** ![moscardo](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/moscardo/32/1307_2.png) [@moscardo](https://discourse.jupyter.org/u/moscardo)\
**Post date:** [September 30, 2020, 1:03pm UTC](https://discourse.jupyter.org/t/mount-external-nfs-or-local-filesystem/6139/12 "2020-09-30T13:03:43Z")

</div>

Root cannot make the change, since it is mounted with no\_root\_squash option, and user=moscardo can do it:

```auto
[root@login home] chown 23446:100 /home/moscardo
chown: changing ownership of ‘moscardo’: Operation not permitted

[moscardo@login ~]$ chown 23446:100 /home/moscardo
[moscardo@login ~]$ 

```

However, all the home directories in that share have proper permissions that there is no need for changing them.

**Update** : It seems that doesn’t matter what I set to CHOWN\_HOME that it always tries to change it

---

<div class="post-metadata">

**Author:** ![wudstrand](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/wudstrand/32/8424_2.png) [@wudstrand](https://discourse.jupyter.org/u/wudstrand)\
**Post date:** [November 13, 2022, 3:09pm UTC](https://discourse.jupyter.org/t/mount-external-nfs-or-local-filesystem/6139/13 "2022-11-13T15:09:14Z")

</div>

@manics How do you do this with a custom spawner?

```python
class CustomSpawner(KubeSpawner):
     def get_env(self):
         env = super().get_env()
         env.update({
             'USER_INFO': get_user_info()
         })
         return env

c.JupyterHub.spawner_class = CustomSpawner

```
