JupyterHub Configuration for WAIIDE
Calliope Integration: This component is integrated into the Calliope AI platform. Some features and configurations may differ from the upstream project.
This guide explains how to configure JupyterHub to spawn and manage WAIIDE containers.
Quick Start Configuration
Add this minimal configuration to your jupyterhub_config.py:
c.JupyterHub.spawner_class = 'dockerspawner.DockerSpawner'
c.DockerSpawner.image = 'calliopeai/waiide:latest'
c.DockerSpawner.network_name = 'jupyterhub-network' # Your Docker network
c.DockerSpawner.volumes = {
'jupyterhub-user-{username}': '/home/{username}'
}Complete Configuration Example
# jupyterhub_config.py
c = get_config()
# Use DockerSpawner to spawn containers
c.JupyterHub.spawner_class = 'dockerspawner.DockerSpawner'
# WAIIDE container image
c.DockerSpawner.image = 'calliopeai/waiide:latest'
# Network configuration (must match your JupyterHub network)
c.DockerSpawner.network_name = 'jupyterhub-network'
c.DockerSpawner.use_internal_ip = True
# Volume mounts for persistent user data
c.DockerSpawner.volumes = {
'jupyterhub-user-{username}': '/home/{username}',
# Optional: Mount shared data
# '/path/to/shared/data': {
# 'bind': '/data',
# 'mode': 'ro'
# }
}
# Environment variables
c.DockerSpawner.environment = {
# Force the main port to 8080 (JupyterHub's expected port)
'PORT': '8080',
# Enable all components (jupyterhub-singleuser + WAIIDE)
'USE_ALL_COMPONENTS': 'true'
}
# Container naming pattern
c.DockerSpawner.name_template = '{username}-waiide'
# Resource limits
c.DockerSpawner.cpu_limit = 2 # CPU cores
c.DockerSpawner.mem_limit = '4G' # Memory
# Remove containers when they stop
c.DockerSpawner.remove = True
# Start container as root (required for permission fixes)
c.DockerSpawner.extra_create_kwargs = {
'user': 'root' # Entrypoint will drop to UID 1000 after fixing permissions
}
# Important: Leave cmd empty to use the container's entrypoint
c.DockerSpawner.cmd = ''
# Set default URL to go directly to WAIIDE IDE
c.Spawner.default_url = '/ide'
# Timeouts for container startup
c.Spawner.http_timeout = 300 # 5 minutes for health checks
c.Spawner.start_timeout = 600 # 10 minutes max startup time
# Debug mode (set to True for troubleshooting)
c.DockerSpawner.debug = FalseImportant Configuration Notes
1. Port Configuration
- WAIIDE uses port 8080 as the main service port (matches JupyterHub’s default)
- WAIIDE Server runs internally on port 8081
- Only expose port 8080 in your spawner configuration
2. Command Configuration
- DO NOT set
c.DockerSpawner.cmdorc.DockerSpawner.args - The container’s entrypoint script handles all startup logic
- It automatically detects JupyterHub environment and starts appropriate services
3. User Permissions
- Container starts as root to fix permissions
- Automatically drops to UID 1000 (standard Jupyter user)
- Home directory is set based on
JUPYTERHUB_USER
4. Environment Variables
The spawner automatically sets these JupyterHub variables:
JUPYTERHUB_SERVICE_PREFIX- URL prefix (e.g.,/user/username/)JUPYTERHUB_USER- UsernameJUPYTERHUB_API_TOKEN- OAuth tokenJUPYTERHUB_API_URL- Hub API URL
Named Servers Configuration
WAIIDE includes fixes for named server OAuth issues, but you may still encounter problems. Options:
Option 1: Disable Named Servers (Recommended)
# Disable named servers to avoid OAuth issues
c.JupyterHub.allow_named_servers = FalseOption 2: Enable Named Servers with Fix
# Enable named servers
c.JupyterHub.allow_named_servers = True
c.JupyterHub.named_server_limit_per_user = 5
# Container naming with server name
c.DockerSpawner.name_template = '{username}-{servername}'
# Apply OAuth scope fix (see troubleshooting guide)KubeSpawner Configuration
For Kubernetes deployments:
c.JupyterHub.spawner_class = 'kubespawner.KubeSpawner'
c.KubeSpawner.image = 'calliopeai/waiide:latest'
c.KubeSpawner.default_url = '/ide'
# Persistent volume
c.KubeSpawner.volumes = [{
'name': 'home',
'persistentVolumeClaim': {
'claimName': 'claim-{username}'
}
}]
c.KubeSpawner.volume_mounts = [{
'name': 'home',
'mountPath': '/home/{username}'
}]
# Resource limits
c.KubeSpawner.cpu_limit = 2
c.KubeSpawner.mem_limit = '4G'
c.KubeSpawner.cpu_guarantee = 0.5
c.KubeSpawner.mem_guarantee = '1G'
# Environment
c.KubeSpawner.environment = {
'PORT': '8080',
'USE_ALL_COMPONENTS': 'true'
}
# Run as root (entrypoint handles privilege drop)
c.KubeSpawner.uid = 0Customization Options
Custom WAIIDE Settings
Mount a custom settings file:
c.DockerSpawner.volumes = {
'jupyterhub-user-{username}': '/home/{username}',
'/path/to/custom/settings.json': {
'bind': '/home/{username}/.WAIIDE-server/data/Machine/settings.json',
'mode': 'ro'
}
}Pre-installed Extensions
Create a derived Docker image:
FROM calliopeai/waiide:latest
# Copy extensions
COPY my-extension /home/calliope/.WAIIDE-server/extensions/my-extensionCustom Workspace
Set a different workspace directory:
c.DockerSpawner.environment = {
'WORKSPACE_DIR': '/home/{username}/projects'
}Monitoring and Health Checks
WAIIDE provides health check endpoints:
/api- Service information/api/status- Basic health check/api/services- Service discovery
JupyterHub automatically uses these for health monitoring.
Troubleshooting
Container Won’t Start
- Check logs:
docker logs <container-name> - Verify network exists:
docker network ls - Ensure image is pulled:
docker pull calliopeai/waiide:latest
403 Forbidden Errors
See the OAuth troubleshooting guide
Slow Startup
- Increase timeouts in spawner configuration
- Check resource limits (CPU/memory)
- WAIIDE Server takes 10-15 seconds to initialize
Security Considerations
- Network Isolation: Use internal Docker networks
- Volume Permissions: Ensure proper ownership of mounted volumes
- Resource Limits: Always set CPU and memory limits
- Image Updates: Regularly update to latest WAIIDE image
Example Configurations
See the example configuration file for a complete working example.