Mount Configmap to userpod

I am new to jupyterhub/jupyter notebook
Can you please suggest the best way to mount configmap to user-pods from hub singleuser configuration?

I am using kubespawner to run jupyterhub and notebook.
I have tried several ways but unable to succeed in that, each config changes tested by me was either not spawning user pod or erroring out hub pod itself.


Are you using zero2jupyterhub? The easiest method is probably to mount a shared volume in all singleuser pods and write your configuration there:

If that’s not what you want could you share whatever configurations you’ve tried? Someone might be able to get it working.

Hey @manics
Thanks for quick response. I am using zero2jupyterhub. So I think you are suggesting to creat config map, mount to hub pod then volume to hub pod and share the to user pod.

Is there a way to directly mount configmap to the user pod when pod starts. (Like we mount to hub)

Can init container also be used to achieve it? i have seen one post on the same (Customizing JupyterHub on Kubernetes)

Though mounting configmap would be straight forward if achievable.

Another way, if we can use lifecycle hook and this hook will only be called before notebook server starts, though i am not sure how to achieve that.



There’s an example of using lifecycle hooks to populate user storage on
If your configmap is a file somewhere you could probably get this to work.

Kubespawner supports initContainers:

though I can’t see an obvious way of using it to put the configmap into your main container.

Hey @manics
Thanks for update, However, i got this working using singleuser config.
As it was a configmap, is it possible to create PVC for files like we create configmap? I have learnt that PVC and PV is for storage classes not for the file use case. Please correct me if i am wrong.

I have configured a mount to user pod using singleuser as follows.
config: '[{"name": "livy-config-json-nm", "mountPath": "/home/jovyan/.jupyter/"}]' '[{"name": "livy-config-json-nm","configMap":{"name": "livy-config-json"}}]'

however, it got mounted as below permissions:

lrwxrwxrwx 1 root   root    31 Oct  8 06:39 -> ..2019_10_08_06_39_11.554462931
lrwxrwxrwx 1 root   root    18 Oct  8 06:39 config.json ->
drwxr-sr-x 2 root    1000 4096 Oct  8 06:39 ..2019_10_08_06_39_11.554462931

error in pod logs

[I 2019-10-08 07:11:12.668 SingleUserNotebookApp restarter:110] KernelRestarter: restarting kernel (3/5), keep random ports
Traceback (most recent call last):
  File "/export/apps/python/3.6.1/lib/python3.6/", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/export/apps/python/3.6.1/lib/python3.6/", line 85, in _run_code
    exec(code, run_globals)
  File "/export/apps/python/3.6.1/lib/python3.6/site-packages/sparkmagic/kernels/sparkkernel/", line 28, in <module>
  File "/export/apps/python/3.6.1/lib/python3.6/site-packages/traitlets/config/", line 657, in launch_instance
  File "</export/apps/python/3.6.1/lib/python3.6/site-packages/>", line 2, in initialize
  File "/export/apps/python/3.6.1/lib/python3.6/site-packages/traitlets/config/", line 87, in catch_config_error
    return method(app, *args, **kwargs)
  File "/export/apps/python/3.6.1/lib/python3.6/site-packages/ipykernel/", line 465, in initialize
  File "/export/apps/python/3.6.1/lib/python3.6/site-packages/ipykernel/", line 376, in init_kernel
  File "/export/apps/python/3.6.1/lib/python3.6/site-packages/traitlets/config/", line 412, in instance
    inst = cls(*args, **kwargs)
  File "/export/apps/python/3.6.1/lib/python3.6/site-packages/sparkmagic/kernels/sparkkernel/", line 23, in __init__
    language_info, session_language, **kwargs)
  File "/export/apps/python/3.6.1/lib/python3.6/site-packages/sparkmagic/kernels/wrapperkernel/", line 29, in __init__
    self.logger = SparkLog(u"{}_jupyter_kernel".format(self.session_language))
  File "/export/apps/python/3.6.1/lib/python3.6/site-packages/sparkmagic/utils/", line 10, in __init__
    super(SparkLog, self).__init__(MAGICS_LOGGER_NAME, conf.logging_config(), class_name)
  File "/export/apps/python/3.6.1/lib/python3.6/site-packages/hdijupyterutils/", line 17, in wrapped_f
    _initialize(overrides, path, fsrw_class)
  File "/export/apps/python/3.6.1/lib/python3.6/site-packages/hdijupyterutils/", line 51, in _initialize
    new_overrides = _load(path, fsrw_class)
  File "/export/apps/python/3.6.1/lib/python3.6/site-packages/hdijupyterutils/", line 63, in _load
    config_text = config_file.read_lines()
  File "/export/apps/python/3.6.1/lib/python3.6/site-packages/hdijupyterutils/", line 23, in read_lines
    with open(self.path, "r+") as f:
PermissionError: [Errno 13] Permission denied: '/home/jovyan/.sparkmagic/config.json'

I did not get a way to change the permission in mountPath config. So I thought of changing ownership to jovyan from root in lifecycle hook and i am getting the error.

singleuser.lifecycle-hooks: '{"postStart":{"exec":{"command": ["/bin/sh", "-c", "chown -R jovyan:users /home/jovyan/.jupyter/*"]}}}'


PostStartHookError: command '/bin/sh -c chown -R jovyan:root /home/jovyan/.jupyter/* > /home/jovyan/message2' exited with 1: chown: changing ownership of ‘/home/jovyan/.jupyter/’: Read-only file system

Can you please help me what can be done here?


Have you tried using subPath?