Skip to content

Update JupyterHub, JupyterLab, and jhub-apps stack - #147

Open
MUFFANUJ wants to merge 15 commits into
nebari-dev:mainfrom
MUFFANUJ:updateJlab&hubDeps
Open

Update JupyterHub, JupyterLab, and jhub-apps stack#147
MUFFANUJ wants to merge 15 commits into
nebari-dev:mainfrom
MUFFANUJ:updateJlab&hubDeps

Conversation

@MUFFANUJ

@MUFFANUJ MUFFANUJ commented Jul 1, 2026

Copy link
Copy Markdown

Reference Issues or PRs

Closes #143 ( needs testing before closing )

What does this implement/fix?

Put a x in the boxes that apply

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds a feature)
  • Breaking change (fix or feature that would cause existing features not to work as expected)
  • Documentation Update
  • Code style update (formatting, renaming)
  • Refactoring (no functional changes, no API changes)
  • Build related changes
  • Other (please describe): Maintenance

Testing

  • Did you test the pull request locally?
  • Did you add new tests?

Documentation

Access-centered content checklist

Text styling

  • The content is written with plain language (where relevant).
  • If there are headers, they use the proper header tags (with only one level-one header: H1 or # in markdown).
  • All links describe where they link to (for example, check the Nebari website).
  • This content adheres to the Nebari style guides.

Non-text content

  • All content is represented as text (for example, images need alt text, and videos need captions or descriptive transcripts).
  • If there are emojis, there are not more than three in a row.
  • Don't use flashing GIFs or videos.
  • If the content were to be read as plain text, it still makes sense, and no information is missing.

Any other comments?

This updates the Nebari data science pack to the newer JupyterHub/JupyterLab runtime stack, including JupyterHub 5.5.0, KubeSpawner 7.0.0, OAuthenticator 17.4.0, JupyterHub chart 4.4.0, JupyterLab 4.6.1, Jupyter Server 2.20, jhub-apps 2026.6.1, and refreshed JupyterLab extensions. Adds compatibility settings for OAuthenticator 17 managed groups and KubeSpawner 7 slug behavior, and adds regression coverage for Keycloak full-path group and PVC slug stability.

Tested by building local Docker images for both the JupyterHub and JupyterLab images from this checkout. The JupyterLab image started successfully on localhost with JupyterLab 4.6.1 and Jupyter Server 2.20, loaded the expected server extensions, and allowed UI smoke testing of the updated Lab experience including Nebi, Gallery/Launchpad, and extension availability. The Hub image started with JupyterHub 5.5.0 and jhub-apps 2026.6.1, and the jhub-apps health endpoint returned OK. The CI-style unit test environment was also run with the updated Hub/OAuthenticator versions, with all 81 unit tests passing. Full Kubernetes spawn/app lifecycle validation should still be done in a deployed environment because the local Docker-only Hub smoke test cannot exercise KubeSpawner, PVC, and cluster networking behavior.

Jupyterlab and extensions: ( the video looks super off due to the high compression since github wont accept vids above 10mbs if needed can add original one )

Screen.Recording.2026-07-02.at.2.35.54.AM.mp4

JupyterHub:

Screen.Recording.2026-07-02.at.2.55.56.AM.mp4

During local validation, jupyter labextension list showed frontend compatibility warnings for the Jupyter AI/chat/collaboration packages. The cause is that JupyterLab 4.6.x uses @jupyter/ydoc v4, while the latest stable Jupyter AI/collaboration packages still declare compatibility with the older v2/v3 range. With the packages available today, the practical options are to either keep JupyterLab 4.6.x and disable/remove Jupyter AI for now, or keep Jupyter AI and use JupyterLab 4.5.8 until upstream publishes stable ydoc-v4-compatible releases.

@krassowski

Copy link
Copy Markdown
Member

During local validation, jupyter labextension list showed frontend compatibility warnings for the Jupyter AI/chat/collaboration packages. The cause is that JupyterLab 4.6.x uses @jupyter/ydoc v4, while the latest stable Jupyter AI/collaboration packages still declare compatibility with the older v2/v3 range.

These warnings are meaning less I believe

With the packages available today, the practical options are to either keep JupyterLab 4.6.x and disable/remove Jupyter AI for now, or keep Jupyter AI and use JupyterLab 4.5.8 until upstream publishes stable ydoc-v4-compatible releases

Does it have any impact on UX?

@krassowski

Copy link
Copy Markdown
Member

The reason to not update to jupyter-ai v3 would be that it depends on jupyter-server-documents.

@krassowski

Copy link
Copy Markdown
Member

Should we also upgrade https://pypi.org/project/jupyterlab-spellchecker/ to 0.9.0 now that it is out with the fix for long-starting notebooks spell checking?

@MUFFANUJ

MUFFANUJ commented Jul 6, 2026

Copy link
Copy Markdown
Author

Should we also upgrade https://pypi.org/project/jupyterlab-spellchecker/ to 0.9.0 now that it is out with the fix for long-starting notebooks spell checking?

Ohh, it was released few hours ago thanks for pointing!

@krassowski

Copy link
Copy Markdown
Member

^it looks like this needs resolving conflicts given #156

@MUFFANUJ
MUFFANUJ requested review from aktech and pmeier as code owners July 15, 2026 14:33
@krassowski

Copy link
Copy Markdown
Member

@MUFFANUJ it looks like it picked up conflicts again. Also, we could grab JupyterLab 4.6.2 with security fixes now.

@krassowski krassowski left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be great to get that in and iterate later. Is there an easy way to test it (PR deploy previews)?

I would defer to @aktech for final review, I am not up to date on what keycloack setup is expected here.

Comment thread config/jupyterhub/00-gateway-auth.py Outdated
Comment thread config/jupyterhub/00-gateway-auth.py
jhub-apps = "==2025.11.1"
jhub-apps = "==2026.6.1"
jupyterlab-nebari-mode = "==0.3.0"
jupyterlab-launchpad = "==1.1.0"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want a newer version of launchpad?

Comment thread config/jupyterhub/00-gateway-auth.py Outdated
Comment thread config/jupyterhub/01-spawner.py Outdated
Comment thread tests/unit/test_keycloak_authenticator.py
@MUFFANUJ
MUFFANUJ requested a review from pmeier August 4, 2026 20:33
@krassowski

Copy link
Copy Markdown
Member

Updating branch to pull lint fix from #207

@krassowski

Copy link
Copy Markdown
Member

@pmeier let me know if you would like me to test this (but I would need some hints on how to). From my PoV it would be good to get out soon given that this bundles a number of vulnerability fixes in Jupyter ecosystem.

With OAuthenticator 17 manage_groups enabled, refresh_user returning
{'auth_state': ...} without a 'groups' key makes JupyterHub fail every
pre-spawn refresh with 'auth_model specifies no groups' (HTTP 500).
Re-derive groups from the preserved oauth_user claims exactly as
update_auth_model does at login.
@tylerpotts

tylerpotts commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

@mikemazara I live-tested this branch on a NIC hetzner-k3s cluster (chart deployed via ArgoCD, images built from head 987d3f8; fork PRs don't publish images, so I mirrored the head to test/pr147-image-build in this repo and ran build-images via workflow_dispatch). The upgraded stack itself came up cleanly: JupyterHub 5.5.0 / KubeSpawner 7.0.0 / OAuthenticator 17.4.0 on the hub, JupyterLab 4.6.2 / Jupyter Server 2.20.0 in spawned pods, and existing-user PVCs survived the KubeSpawner 7 slug change.

First blockers found that has been fixed:

Every spawn by an OAuth-logged-in user fails with HTTP 500 (fix pushed to this branch)

refresh_user in config/jupyterhub/00-gateway-auth.py returns {"auth_state": new_state} with no groups key. This PR enables manage_groups = True (required for admin_groups under OAuthenticator 17) plus refresh_pre_spawn = True, and JupyterHub hard-fails a pre-spawn refresh whose auth model lacks groups:

Error starting server admin: Authenticator.manage_groups is enabled, but auth_model for admin specifies no groups. Does KeyCloakOAuthenticator support manage_groups=True?

Users created through the REST API dodge it (no refresh token, so refresh_user bails early), which is probably why it slipped past testing; anyone who logged in through Keycloak hits it on every spawn. I pushed d3c933f to this branch: when manage_groups is on, refresh_user re-derives auth_model["groups"] from the preserved oauth_user claims via get_user_groups, matching what update_auth_model does at login. Verified on the live cluster (admin spawn 500 -> 202) and unit tests pass under this PR's CI pins.

Remaining blocker:

Dark mode: hub-rendered pages are unreadable (black headers on dark background)

JupyterHub >= 5.2 auto-follows the OS color scheme (jupyterhub/jupyterhub#4897) and sets data-bs-theme="dark", but jhub-apps 2026.6.1 ships no dark styling for the server-rendered hub pages (hub.css doesn't exist in that release), so the spawn page renders black header text on a dark background for any user whose OS is in dark mode. jhub-apps 2026.7.1 adds data-bs-theme-scoped hub page styles, a color-mode toggle, and syncs its preference with JupyterHub's own theme key (nebari-dev/jhub-apps#704, nebari-dev/jhub-apps#707). I'll test the newer jhub-apps version next week and follow up here; the bump shouldn't land in this PR until that's verified against the new hub stack.

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Per-user Nebi (jupyter-server-proxy) crash-loops under jupyter-server 2.20

5 participants