JupyterHub Basics

This page covers the fundamentals you need to work in a UZH JupyterHub deployment — from launching your server to managing files and Python environments.


The JupyterLab interface

JupyterLab is the web-based environment you see after logging in. It provides a file browser, notebook editor, terminal, and more.

Key areas of the UI:

Area Description
Left sidebar File browser, running terminals & kernels, table of contents
Main work area Open notebooks, scripts, terminals — arrange in tabs or splits
Status bar Kernel name and status, line/column position
Launcher Opens a new notebook, console, or terminal

Using Git in JupyterLab

You can use Git directly from the terminal or via the built-in Git extension.

Open a terminal from the Launcher and use standard git commands, or click the Git icon git in the left sidebar for a visual interface.

Do not store credentials (or, in fact, anything really secret) on a JupyterHub server. Your team-mates (on a group-server), teachers, IT staff, will all have access to your files as one and the same user, jovyan. We recommend short-lived github tokens.

Distributing materials with nbgitpuller

nbgitpuller is pre-installed in the standard course images. It lets teachers hand out a single click-to-open link that clones a Git repository into a participant’s home directory — and, on later clicks, merges updates without overwriting the participant’s own changes.

Generate a link with the nbgitpuller link generator:

Field What to enter
JupyterHub URL The hub URL you reach once you are logged in (e.g. https://<course>.zi.uzh.ch) — not the OLAT/LMS link
Git repository URL The HTTPS URL of the repository to pull (e.g. a GitLab or GitHub repo)
Branch The branch to pull (optional; defaults to the repo’s default branch)
File to open A notebook or folder to open after pulling (optional)

Share the generated link with participants. Opening it logs them in (if needed), clones or updates the repository under /home/jovyan, and opens the requested file. See the nbgitpuller documentation for details on the underlying auto-merge behaviour.

👩‍🎓 Participants: If your teacher sends you an nbgitpuller link (it loads course materials into your home directory), you can simply click it — it logs you in if needed and copies the latest materials for you. Your own changes are preserved.


Python virtual environments and kernels

Each notebook runs against a kernel — a running Python process. The kernels available in the Launcher correspond to Python environments installed on your server.

What survives a server restart — and what doesn’t

Location Survives restart?
Files and virtual environments under /home/jovyan ✅ Yes — this is a persistent volume
Packages you install with pip install (they go to ~/.local) ✅ Yes — ~/.local lives under /home/jovyan
The pre-installed base environment itself ♻️ Reset on restart — it lives in the container image and is rebuilt fresh

On the UZH course images, pip is configured (via PIP_USER=1) so that pip install <package> installs into your personal ~/.local directory by default. Because ~/.local sits inside your persistent /home/jovyan, those packages survive restarts and are picked up by the base-environment kernel. In other words, pip install is the supported way to persistently extend the pre-configured base environment — you keep all the packages your course already provides and simply add your own on top.

The base environment image layer is still rebuilt fresh on every restart, so you can never permanently break it: if one of your ~/.local packages ever wedges things, removing it (or clearing ~/.local) returns you to a clean base.

When to create a dedicated virtual environment instead

Extending the base environment with pip install is convenient, but everything lands in one shared ~/.local. Create a dedicated virtual environment when you want:

  • isolation — a self-contained set of packages that can’t clash with the base environment or with another project, or
  • reproducibility — a clean, separately-registered kernel you can recreate from a requirements.txt (see Sharing an environment definition).

Creating a custom kernel

The quickest way is the bundled new-venv-kernel helper. Open a terminal from the Launcher and run:

# Create a virtual environment and register it as a Jupyter kernel
new-venv-kernel myenv numpy pandas matplotlib   # add whatever packages you need

This creates a virtual environment under ~/my-venvs/myenv, installs the packages you list (plus ipykernel), and registers a kernel named Python (myenv). Refresh the Launcher (or reload the page) — the new kernel will appear as an option.

Prefer to do it by hand? The helper is equivalent to:

# 1. Create a virtual environment in your home directory
python -m venv ~/my-venvs/myenv

# 2. Install your packages (ipykernel is required to register the kernel)
~/my-venvs/myenv/bin/pip install ipykernel numpy pandas matplotlib

# 3. Register the environment as a Jupyter kernel
~/my-venvs/myenv/bin/python -m ipykernel install --user --name myenv --display-name "Python (myenv)"

Where does the environment live?
The virtual environment is created under ~/my-venvs/myenv, which is inside /home/jovyan — your persistent home directory. The kernel registration is stored under ~/.local/share/jupyter/kernels/myenv, also inside /home/jovyan. Both survive server restarts.

Sharing an environment definition

To make your environment reproducible, export its package list to a file:

~/my-venvs/myenv/bin/pip freeze > requirements.txt

Anyone with that file — including your future self after losing an environment — can recreate it with:

new-venv-kernel myenv -r requirements.txt

or by hand:

python -m venv ~/my-venvs/myenv
~/my-venvs/myenv/bin/pip install ipykernel -r requirements.txt
~/my-venvs/myenv/bin/python -m ipykernel install --user --name myenv --display-name "Python (myenv)"

👩‍🎓 Participants: Course environments are pre-configured by your teacher. To add an extra package, pip install <package> is usually enough — on the course images it installs into your persistent ~/.local and extends the base environment (see What survives a restart). Create a dedicated virtual environment (as shown above) when you need an isolated, reproducible setup.

👩‍🏫 Owners / Coaches: Pre-installed kernels are baked into the server Docker image, which is built and deployed by ZI. To add a kernel or package for the whole course, contact ZI so it can be added to the course image. You can also provide a requirements.txt to participants so they can recreate the exact environment in their own server.


UZH persistent volumes

Each JupyterHub deployment provides two persistent storage areas:

  1. /home/jovyan — your personal home directory. Notebooks, data files, and custom virtual environments stored here survive server restarts.
  2. /home/jovyan/shared — a read-only directory (symbolic link to /home/shared) shared with the whole course.

Both volumes are backed by Azure Blob Storage over NFS, which means they are network-attached and not limited by the number of disks a virtual machine can hold. This allows many students to run concurrently on the same node.

Key points:

  • /home/jovyan — your personal persistent directory. Files here are not lost when your server stops. Each user’s data is stored in a separate subdirectory on the shared volume, isolated by username. It is private — other participants cannot see it.
  • /home/jovyan/shared — read-only course materials provided by your teacher. It is not a place to exchange files with classmates: you cannot write to it.
  • /tmp — temporary storage, cleared on restart. Do not store important work here.

Sharing files within a team? The shared directory is read-only and only your teacher can put files there, so it cannot be used to exchange files with team-mates. To work on the same files together, ask your teacher to put your team on a collaboration group server, where all group members share one home directory. See Roles, Groups & Collaboration.

👩‍🎓 Participants: Always save your work under /home/jovyan. If you need to download large datasets temporarily, use /tmp to avoid filling your home directory. If you run out of space, contact your course administrator.

To bring your own files in, drag them from your computer onto the file browser in the left sidebar of JupyterLab (or use its upload button). They are stored under /home/jovyan and survive restarts.

👩‍🏫 Owners / Coaches: User home directories are served by a single shared Blob NFS PersistentVolumeClaim (blob-homes-pvc) with per-user subdirectories. There is no per-user storage quota at the Kubernetes level — monitoring storage usage should be done at the Azure storage account level.

Writing to the shared volume (/home/shared) is possible by uploading to the shared-materials container (jupyterhub) in the Azure storage account — this is a different container from the one holding user home directories (jupyterhub-homes). A usage guide for this will be provided to you by ZI.


UZH ZI Cloud —

This site uses Just the Docs, a documentation theme for Jekyll.