mirror of
https://github.com/stellarshenson/stellars-jupyterhub-ds.git
synced 2026-03-08 06:00:29 +00:00
Added VOLUME_DESCRIPTIONS config dict allowing optional user-friendly
descriptions for volumes shown in management UI.
Changes:
- Added VOLUME_DESCRIPTIONS dict in jupyterhub_config.py (optional, co-defined
with DOCKER_SPAWNER_VOLUMES)
- Exposed volume_descriptions via c.JupyterHub.template_vars
- Updated home.html to conditionally display descriptions if defined
- If volume not in VOLUME_DESCRIPTIONS, no description shown (UI remains agnostic)
Configuration example:
VOLUME_DESCRIPTIONS = {
'home': 'User home directory files, configurations',
'workspace': 'Project files, notebooks, code',
'cache': 'Temporary files, pip cache, conda cache'
}
Documentation:
- Updated .claude/CLAUDE.md with Manage Volumes implementation details
- Simplified Restart Server section for consistency
- Added template variables to doc/ui-template-customization.md
UI now shows volume name, Docker volume path, and optional description
(if configured). Fully backward compatible - descriptions are optional.
1.9 KiB
1.9 KiB
UI Template Customization
JupyterHub templates extended using Jinja2 to add custom UI features (server restart, volume management, notifications). Templates placed in services/jupyterhub/templates/ and copied to /srv/jupyterhub/templates/ during Docker build.
Key Technical Facts:
- Templates extend base using
{% extends "page.html" %} - Override blocks:
{% block main %},{% block script %} - Changes require Docker rebuild with
--no-cacheflag - JupyterHub 5.4.2 uses Bootstrap 5 (not Bootstrap 4)
Template Variables (via c.JupyterHub.template_vars):
user_volume_suffixes: List of volume suffixes fromDOCKER_SPAWNER_VOLUMESvolume_descriptions: Optional dict mapping suffixes to descriptions
JavaScript Integration: All custom JavaScript wrapped in RequireJS to ensure library loading:
require(["jquery"], function($) {
"use strict";
// Custom code here
});
Bootstrap 5 Modal Syntax:
<button data-bs-toggle="modal" data-bs-target="#myModal">
<i class="fa fa-rotate" aria-hidden="true"></i> Restart
</button>
CSRF Protection:
All POST requests include XSRF token via X-XSRFToken header:
headers: { 'X-XSRFToken': getCookie('_xsrf') }
Custom Handlers (registered in jupyterhub_config.py):
c.JupyterHub.extra_handlers = [
(r'/api/users/([^/]+)/manage-volumes', ManageVolumesHandler),
(r'/api/users/([^/]+)/restart-server', RestartServerHandler),
(r'/api/notifications/broadcast', BroadcastNotificationHandler),
(r'/notifications', NotificationsPageHandler),
]
Font Awesome Icons:
- Restart:
fa fa-rotate - Volumes:
fa fa-database - Stop:
fa fa-stop - Start:
fa fa-play
Build Process:
docker compose build --no-cache jupyterhub
docker stop stellars-jupyterhub-ds-jupyterhub && docker rm stellars-jupyterhub-ds-jupyterhub
docker compose up -d jupyterhub