- Add JUPYTERHUB_BASE_URL_PREFIX that handles root path case
- When BASE_URL is '/', '', or None, prefix becomes empty string
- Prevents //hub/home redirect issue when using root path routing
- docker-sock: mounts /var/run/docker.sock (container orchestration)
- docker-privileged: runs with --privileged flag (hardware access)
Updated pre_spawn_hook to check both groups and set spawner.volumes
or spawner.privileged accordingly. Documentation updated.
Added --no-startup flag to Watchtower command in compose.yml.
Previously, Watchtower would check for image updates on every container
startup/restart. Now only runs at scheduled time (midnight daily).
Removed obsolete 01_nvidia-smi.sh (GPU detection handled in jupyterhub_config.py).
Renamed 02_ensure_groups.py to 01_ensure_groups.py for sequential ordering.
Changed from containrrr/watchtower:latest to nickfedor/watchtower:latest.
New image is actively maintained and compatible with latest Docker versions.
Version bump: 3.2.11 -> 3.3.1
Added Volume Architecture diagram showing four persistent volumes per user with Docker host to container mount mapping. Diagram illustrates jupyterlab-{username}_* naming pattern for user-specific volumes (home, workspace, cache) and shared jupyterhub_shared volume. Shows mount points and example contents for each volume type, with note about CIFS mount capability for NAS integration.
Added three mermaid diagrams to README documenting system architecture and workflows. Configuration Flow diagram shows how environment variables from compose.yml flow through jupyterhub_config.py to spawned user containers, including DOCKER_SPAWNER_VOLUMES, VOLUME_DESCRIPTIONS, BUILTIN_GROUPS, pre_spawn_hook, extra_handlers, and template_paths. GPU Auto-Detection diagram illustrates the auto-detect mechanism with temporary CUDA container spawning nvidia-smi for detection. User Self-Service Workflow diagram demonstrates home page state management for restart server and manage volumes features. Converted HTML alert divs to GitHub-style WARNING blocks for better rendering.
Added journal entry #13 documenting release v3.2.11 preparation:
- Git tag creation with annotations
- RELEASE.md delta notes
- Documentation simplification (docker-socket-permissions.md from 66 to 19 lines)
- project.env update with release metadata
- Security warning corrections (host system -> Docker host)
- HTML alert styling for warnings
Updated README.md to explicitly name 'docker-privileged' group in opening
description of privileged access section for clarity.
Updated version metadata:
- VERSION_COMMENT reflects key features of v3.2.11
- Added RELEASE_TAG: RELEASE_3.2.11
- Added RELEASE_DATE: 2025-11-09
This marks the official release of version 3.2.11 with configuration-agnostic
volume management, notification broadcast, and privileged access control.
Delta release notes covering changes from v3.0.14 to v3.2.11:
- Configuration-agnostic volume management with optional descriptions
- Admin notification broadcast system
- Privileged user docker.sock access control
- Documentation following modus primaris style
- Technical improvements and upgrade notes
Following modus primaris: concise, factual, organized sections.
Added entry #12 documenting volume management refactoring to be fully
configuration-agnostic with optional descriptions, import error fixes for
jupyterhub_config.py, and README/documentation simplification following
modus primaris style.
Fixed NameError when custom_handlers.py imports from jupyterhub_config.py
by protecting all c.* assignments with 'if c is not None:' checks.
Changes:
- Wrapped c = get_config() in try-except to handle module import context
- Defined DOCKER_SPAWNER_VOLUMES as module-level constant
- Modified get_user_volume_suffixes() to accept volumes dict parameter
- USER_VOLUME_SUFFIXES calculated from constant (importable without c defined)
- Protected all c.* configuration assignments with 'if c is not None:' guards
This allows custom_handlers.py to import USER_VOLUME_SUFFIXES without
triggering "NameError: name 'get_config' is not defined" when the config
file is imported as a module rather than loaded by JupyterHub.
Volume management now works correctly - configuration can be safely imported
by handlers to validate volume names against USER_VOLUME_SUFFIXES.
Updated volume management to dynamically read volume names from
DockerSpawner.volumes configuration instead of hardcoding them:
- Added get_user_volume_suffixes() function to extract volume suffixes from
config matching jupyterlab-{username}_<suffix> pattern
- Exposed USER_VOLUME_SUFFIXES via c.JupyterHub.template_vars for templates
- Updated home.html to use Jinja2 loop generating checkboxes dynamically
from user_volume_suffixes variable
- Modified ManageVolumesHandler to validate against configured volumes
instead of hardcoded {'home', 'workspace', 'cache'}
- Removed volume descriptions (e.g., "Contains: User home directory...") to
keep UI truly agnostic
Now works correctly if volumes are renamed, added, or removed in configuration
without requiring template or handler changes. Volume names displayed exactly
as defined in config (home, workspace, cache by default).
Restructured README.md following modus primaris approach:
1. Simplified intro (one concise paragraph)
2. Features as bullet points at top
3. User Interface screenshots (with explanations before images)
4. Architecture diagram and explanation
5. Remaining sections (References, Requirements, Quickstart, etc.)
Removed duplicate Features and User Interface sections that were previously
positioned after Architecture. Content now flows logically from high-level
features to visual examples to technical architecture details.
Reordered User Interface section:
- Home control panel (server restart and volume management)
- Volume management screenshots grouped together
- Admin notification broadcast (last)
Changed format: explanation text with heading before each screenshot image,
replacing italic captions below images for better readability.
Updated entry #11 to accurately reflect the super-minimal modus primaris style
approach with line counts for each documentation file (35, 55, 66 lines) and
emphasis on "glimpse of implementation" rather than comprehensive coverage.
Added entry #11 documenting comprehensive documentation creation for
notification system, UI customization, and Docker socket permissions. Also
documented screenshot updates in README.md replacing restart server image with
complete control panel view and adding admin notification broadcast interface.