- add JUPYTERLAB_AUX_SCRIPTS_PATH env var for admin-managed startup
scripts in user containers, default /mnt/shared/start-platform.d
- pass JUPYTERLAB_AUX_SCRIPTS_PATH to DockerSpawner.environment
- expand README Custom Branding from logo-only to full table covering
logo, favicon, lab main icon, and lab splash icon
- add README Admin Startup Scripts section
- add User Environment category in settings_dictionary.yml
- add JUPYTERLAB_AUX_SCRIPTS_PATH to Dockerfile defaults
- add JUPYTERHUB_LAB_MAIN_ICON_URI and JUPYTERHUB_LAB_SPLASH_ICON_URI
for custom JupyterLab main toolbar logo and splash screen icon
- file:// URIs copy to hub static dir and resolve to hub static URL,
external URLs passed through as-is
- resolved URIs injected conditionally into DockerSpawner.environment
as JUPYTERLAB_MAIN_ICON_URI and JUPYTERLAB_SPLASH_ICON_URI
- fix spawner env var names to match lab image expectations:
JUPYTERHUB_SERVICE_* -> ENABLE_SERVICE_* (MLflow, Resources Monitor,
TensorBoard), remove duplicate JUPYTERHUB_GPU_ENABLED
- update custom-branding.md with JupyterLab Icons section
JUPYTERHUB_LOGO_URI previously defaulted to file:///srv/jupyterhub/logo.svg
which doesn't exist in the image - the os.path.exists() check silently
fell through to stock JupyterHub logo anyway. Changed default to empty
across Dockerfile, config, compose.yml, and settings_dictionary.yml.
Both JUPYTERHUB_LOGO_URI and JUPYTERHUB_FAVICON_URI now consistently
default to empty, meaning stock JupyterHub assets are used unless
explicitly configured.
Mirrors the existing JUPYTERHUB_LOGO_URI pattern:
- file:// URIs copy the file to JupyterHub static dir at startup
- http(s):// URLs passed directly to template as link href
- empty/unset falls back to default static_url('favicon.ico')
Enables visual differentiation between dev/staging/prod deployments.
Session Extension Feature:
- Add JUPYTERHUB_IDLE_CULLER_MAX_EXTENSION env var (default 24h)
- Add SessionInfoHandler and ExtendSessionHandler API endpoints
- Add Session Status card to home page with countdown timer
- Extension tracking in spawner state (resets on server restart)
- Color-coded warnings (yellow <1h, red <30min)
Environment Settings Harmonization:
- Add all ENV defaults to Dockerfile
- Add idle culler settings to compose.yml
- Standardize logo as JUPYTERHUB_LOGO_URI with file:// prefix
- Update NVIDIA_IMAGE to nvidia/cuda:13.0.2-base-ubuntu24.04
- Add notifications page styling (form, textarea, results table)
- Unify button font sizes to 0.8rem across all pages
- Set collapsed user card padding to 0
- Add subtle hover effect on admin user rows (0.015 alpha)
- Style Add Users form panel with dark mode support
- Style authorization and token pages consistently
- Add CERTIFICATE_DOMAIN_NAME to compose.yml (defaults to localhost)
- Update 00_generate_ssl_cert.sh to use env variable
- Allows custom domain names for self-signed certificates
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).
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
- Add pull_policy: build to jupyterhub service
- Forces Docker Compose to use locally built image
- Prevents unnecessary pulls from Docker Hub after building
Now 'docker compose up' will use the local image built with 'make build'
- Change Docker build context from services/jupyterhub to project root
- Copy config/jupyterhub_config.py into image at /srv/jupyterhub/jupyterhub_config.py
- Users can still override with volume mount if needed
- Update all COPY paths in Dockerfile to reflect new build context
- Enables container to work out-of-the-box without external config file
Benefits:
- Image is self-contained and ready to run without dependencies
- Volume mount remains optional for custom configurations
- Default config includes GPU auto-detection and self-service features