diff --git a/.env_example b/.env_example index d9056ae..0d02285 100644 --- a/.env_example +++ b/.env_example @@ -1,6 +1,3 @@ -# THIS IS AN EXAMPLE -# CHANGE IT IN PRODUCTION - # Postgres Setup POSTGRES_DB=jupyter POSTGRES_USER=jupyter @@ -18,8 +15,11 @@ SPAWNER_DEFAULT_URL=/lab NOTEBOOK_MEMORY_LIMIT=500M NOTEBOOK_CPU_LIMIT=1.0 HUB_IP=jupyterhub # Name of the Docker container +DOCKER_NOTEBOOK_DIR=/home/jovyan/work +DOCKER_SPAWNER_DEBUG=0 # Set to non Zero to enable # Docker +COMPOSE_PROJECT_NAME=ifn_stack DOCKER_NETWORK_NAME=jupyter_network POSTGRES_PORT=5432 JUPYTERHUB_PORT=8000 diff --git a/jupyterhub/jupyterhub_config.py b/jupyterhub/jupyterhub_config.py index c55b332..7676a7f 100644 --- a/jupyterhub/jupyterhub_config.py +++ b/jupyterhub/jupyterhub_config.py @@ -95,61 +95,44 @@ c.JupyterHub.template_paths = ["/etc/jupyterhub/templates"] # Hub environment for containers + +# Spawn Single-User-Servers as Docker Containers c.JupyterHub.spawner_class = DockerSpawner -c.Spawner.ip = "0.0.0.0" + +# Spawn Containers from this Image c.DockerSpawner.image = os.environ.get( "NOTEBOOK_IMAGE", "jupyter/scipy-notebook:latest" ) -'''network_name = os.environ.get('DOCKER_NETWORK_NAME', 'stack_default') -c.DockerSpawner.network_name = network_name -c.DockerSpawner.extra_host_config = { - 'network_mode': network_name -} -c.DockerSpawner.remove = True -c.DockerSpawner.debug = True -c.DockerSpawner.default_url = os.environ.get('SPAWNER_DEFAULT_URL', '/lab') -c.DockerSpawner.use_internal_ip = True -# Resources -c.DockerSpawner.mem_limit = os.environ.get('NOTEBOOK_MEMORY_LIMIT', '500M') -c.DockerSpawner.cpu_limit = float(os.environ.get('NOTEBOOK_CPU_LIMIT', '1.0')) +# Connect Containers to this network +network_name = os.environ.get("DOCKER_NETWORK_NAME", "stack_default") +c.DockerSpawner.use_internal_ip = True # Let docker manage network communications +c.DockerSpawner.network_name = network_name -# Volume -c.DockerSpawner.volumes = { - '/var/run/docker.sock': '/var/run/docker.sock' -# './data/jupyter/users/{username}': '/home/jovyan/work', -# './data/jupyter/nbgrader/exchange': '/srv/nbgrader/exchange', -# './data/jupyter/nbgrader/courses': '/srv/nbgrader/courses', -} +# Explicitly set notebook directory because we'll mounting a volume to it. +notebook_dir = os.environ.get("DOCKER_NOTEBOOK_DIR", "/home/jovyan/work") +c.DockerSpawner.notebook_dir = notebook_dir -c.DockerSpawner.notebook_dir = '/home/jovyan/work' +# Mount real User docker volume to the host +c.DockerSpawner.volumes = {"jupyterhub-user-{username}": notebook_dir} -# Container Environment -c.DockerSpawner.environment = { - 'GRANT_SUDO': '0', - 'JUPYTER_ENABLE_LAB': os.environ.get('ENABLE_LAB', '1'), - 'JUPYTERHUB_SINGLEUSER_APP': 'jupyter_server.serverapp.ServerApp' -} +# Remove Containers once there stopped +c.DockerSpawner.remove = True -#c.DockerSpawner.hub_ip_connect = os.environ.get('HUB_IP', 'jupyterhub') -#c.DockerSpawner.hub_port_connect = 8081 +# For Debbugging (passed to spawned Containers) +ds_debug = True if int(os.environ.get("DOCKER_SPAWNER_DEBUG", "0")) else False +c.DockerSpawner.debug = ds_debug -def pre_spawn_hook(spawner): - """Create user directories before spawning""" - username = spawner.user.name - user_dir = f"./data/jupyter/users/{username}" +# Dont mess with this +# The Spawner sits inside a docker container which manages +# everything network related +c.Spawner.ip = "0.0.0.0" - import os - import stat - if not os.path.exists(user_dir): - os.makedirs(user_dir, mode=0o755, exist_ok=True) - os.chown(user_dir, 1000, 1000) +# Set Resource Limits +c.DockerSpawner.mem_limit = os.environ.get("NOTEBOOK_MEMORY_LIMIT", "500M") +c.DockerSpawner.cpu_limit = float(os.environ.get("NOTEBOOK_CPU_LIMIT", "1.0")) - # TODO Nbgrader dirs - -c.DockerSpawner.pre_spawn_hook = pre_spawn_hook -''' """ # Services configuration for NBGrader @@ -223,14 +206,3 @@ c.JupyterHub.concurrent_spawn_limit = 10 # Allow named servers c.JupyterHub.allow_named_servers = True c.JupyterHub.named_server_limit_per_user = 3 - -print("JupyterHub configuration loaded successfully!") -print(f"Base URL: {c.JupyterHub.base_url}") -print(f"Bind URL: {c.JupyterHub.bind_url}") -print(f"Database URL: {c.JupyterHub.db_url}") -print(f"Docker Network: {c.DockerSpawner.network_name}") -print(f"Docker Image: {c.DockerSpawner.image}") -print("Postgres available", is_service_available_cmd("postgres", 5432)) - -with open("/srv/jupyterhub/cookie_secret") as f: - print(f.readlines())