Note: This is the research document of jupyterhub setup with helm.
purpose:
This
project provides a complete setup of JupyterHub on Kubernetes using
Helm, tailored for multi-user environments with resource customization
and persistent storage. It includes user management with support for
local or external authentication and a dynamic spawner form integrated
with KubeSpawner. The spawner form enables configuration of Docker
image, GPU device(s), CPU and RAM allocation, and Time-To-Live (TTL) for
automatic notebook cleanup. However, resource selection is restricted
to admins only—regular users cannot choose or modify resource
configurations themselves. Each user's working directory is persistently
stored using PVCs (Persistent Volume Claims), ensuring data retention
across sessions. This setup is ideal for shared GPU servers or research
environments where users need isolated, configurable Jupyter notebook
instances on-demand under admin-controlled resource policies.
Project workflow
Helm installation
Jupyterhub installation with helm chart.
Assign GPU to users.
Image selection for users at the time of profile creation.
This will create namespace: jupyter
check this with,
kubectl get ns
Switch to default jupyter namespace so you dont have to write namespace every time:
kubectl config set-context --current --namespace=jupyter
Revert back to default namespace:
kubectl config set-context --current --namespace=default
Below are some post installation checks:
Verify that created Pods enter a Running state:
kubectl --namespace=jupyter get pod
If a pod is stuck with a Pending or ContainerCreating status, diagnose with:
`kubectl --namespace=jupyter describe pod <name of pod>`
If a pod keeps restarting, diagnose with:
`kubectl --namespace=jupyter logs --previous <name of pod>`
Verify an external IP is provided for the k8s Service proxy-public.
kubectl --namespace=jupyter get service proxy-public
If the external ip remains , diagnose with:
kubectl --namespace=jupyter describe service proxy-public
Verify web based access:
You have not configured a k8s Ingress resource so you need to access the k8s
Service proxy-public directly.
If your computer is outside the k8s cluster, you can port-forward traffic to
the k8s Service proxy-public with kubectl to access it from your
computer.
When trying to create user for the first time then it will go to pending state.
if face error,
Type Reason Age From Message
Warning FailedScheduling 2m31s jhub-user-scheduler 0/1
nodes are available: pod has unbound immediate PersistentVolumeClaims.
preemption: 0/1 nodes are available: 1 Preemption is not helpful for
scheduling.
Then the reason behind this is Dynamic storage volume is not found.
Solution:
Create Dynamic PVC:
kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml
Option 1: (not recommended )
First do add user from admin panel.
Then do signup with that user and change password.
Option 2:
1.Do signup from the login page. And the request of authorization is go to administrator.
Admin can authorize user via - http://127.0.0.1:30235/hub/authorize
- display_name: "GPU 6"description: "Access to GPU ID 6"slug: "gpu6"kubespawner_override:
image: quay.io/jupyter/r-notebook:2025-07-28# image: quay.io/jupyterhub/k8s-singleuser-sample:4.2.0extra_resource_limits:
nvidia.com/gpu: "6"environment:
NVIDIA_VISIBLE_DEVICES: "6"
Complete Project with resource selection:
This
project provides a complete setup of JupyterHub on Kubernetes using
Helm, tailored for multi-user environments with resource customization
and persistent storage. It includes user management with support for
local or external authentication and a dynamic spawner form integrated
with KubeSpawner. The spawner form enables configuration of Docker
image, GPU device(s), CPU and RAM allocation, and Time-To-Live (TTL) for
automatic notebook cleanup. However, resource selection is restricted
to admins only—regular users cannot choose or modify resource
configurations themselves. Each user's working directory is persistently
stored using PVCs (Persistent Volume Claims), ensuring data retention
across sessions. This setup is ideal for shared GPU servers or research
environments where users need isolated, configurable Jupyter notebook
instances on-demand under admin-controlled resource policies.