from traitlets.config import get_config import os # Minimal JupyterHub config for local multi-user usage inside docker-compose. # This config is intentionally small — customize for auth, spawners, and TLS in production. c = get_config() # Hub internal URL (where the hub process listens for /hub requests) c.JupyterHub.bind_url = 'http://:8081/hub/' # Hub IP for spawned containers to connect back (use container name on Docker network) c.JupyterHub.hub_connect_ip = 'jupyterhub' # Proxy configuration # - Proxy public address (what users access): default is port 8000, we want 8001 # - Proxy API address (hub talks to proxy control): separate port 8002 c.JupyterHub.port = 8001 # Public proxy port c.ConfigurableHTTPProxy.api_url = 'http://127.0.0.1:8002' # Lightweight built-in authenticator: no external package required. This is # intended only for local development/testing. It accepts any username as long # as the password equals the value of JUPYTER_PASSWORD (default: einszwo4). from jupyterhub.auth import Authenticator class SimpleEnvPasswordAuthenticator(Authenticator): async def authenticate(self, handler, data): """Authenticate any username when the shared env password matches. Dev-only: returns the username on success, otherwise None. """ username = data.get('username') password = data.get('password') if not username or not password: return None if password == os.environ.get('JUPYTER_PASSWORD', 'einszwo4'): return username return None # Use the in-file authenticator for dev/testing c.JupyterHub.authenticator_class = SimpleEnvPasswordAuthenticator # Allow any authenticated user to access (suppress the warning) c.Authenticator.allow_all = True # Use DockerSpawner for production-ready containerized user servers from dockerspawner import DockerSpawner c.JupyterHub.spawner_class = DockerSpawner # Docker image for single-user notebook servers c.DockerSpawner.image = 'jupyter/scipy-notebook:latest' # Connect to Docker socket c.DockerSpawner.use_internal_ip = True c.DockerSpawner.network_name = 'einszwovier_network' # Remove containers after they stop c.DockerSpawner.remove = True # Mount the data directory for persistent storage # Use the data directory we already have mounted in docker-compose c.DockerSpawner.volumes = { 'jupyterhub-user-{username}': {'bind': '/home/jovyan/work', 'mode': 'rw'} } # Increase spawn timeout c.Spawner.start_timeout = 120 c.Spawner.http_timeout = 120 # Set notebook directory and default interface c.Spawner.notebook_dir = '/home/jovyan/work' c.Spawner.default_url = '/lab' # UI and data locations c.JupyterHub.logo_file = '/srv/jupyterhub/logo.png' c.JupyterHub.cookie_secret_file = '/srv/jupyterhub/jupyterhub_cookie_secret' # Note: DockerSpawner creates isolated containers for each user. # Each user gets their own containerized Jupyter environment with persistent storage.