79 lines
2.9 KiB
Python
79 lines
2.9 KiB
Python
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.
|