-
Notifications
You must be signed in to change notification settings - Fork 3
Jupyterhub Configuration
This page should describe the Jupyterhub configuration file jupyterhub_config.py
.
First of all I'd like to start with the 'basic' Jupyterhub configuration. There one can find the network configuration (ip,port,hub_ip), the security configuration (ssl_key, ssl_cert, admin_access, cookie_secret_file, admin_users), the Authenticator Class and the Spawner Class.
import os
c.JupyterHub.ip = os.environ.get('JUPYTERHUB_IP')
c.JupyterHub.port = int(os.environ.get('JUPYTERHUB_PORT'))
c.JupyterHub.hub_ip = os.environ.get('JUPYTERHUB_HUB_IP')
c.JupyterHub.spawner_class = 'cassinyspawner.SwarmSpawner'
c.JupyterHub.authenticator_class = 'ldapauthenticator.LDAPAuthenticator'
c.JupyterHub.ssl_key = os.environ['SSL_KEY']
c.JupyterHub.ssl_cert = os.environ['SSL_CERT']
c.JupyterHub.log_level = os.environ.get('JUPYTERHUB_LOG_LEVEL')
c.JupyterHub.admin_access = True
data_dir = os.environ.get('JUPYTERHUB_DATA_VOLUME')
c.JupyterHub.db_url = os.path.join('sqlite:///', data_dir, 'jupyterhub.sqlite')
c.JupyterHub.cookie_secret_file = os.path.join(data_dir,'jupyterhub_cookie_secret')
c.Authenticator.admin_users = admin = set()
pwd = os.path.dirname(__file__)
with open(os.path.join(pwd, 'userlist')) as f:
for line in f:
if not line:
continue
parts = line.split()
name = parts[0]
if len(parts) > 1 and parts[1] == 'admin':
admin.add(name)
One can read the whole documentation about the Jupyterhub config here.
As defined in the c.JupyterHub.authenticator_class
property above, this project uses the LDAP Authenticator. If you don't have a LDAP Server in your setup you can choose from various other here or even create a new one.
c.LDAPAuthenticator.server_address = os.environ.get('LDAPAUTHENTICATOR_SERVER_ADDRESS')
c.LDAPAuthenticator.server_port = int(os.environ.get('LDAPAUTHENTICATOR_SERVER_PORT'))
c.LDAPAuthenticator.lookup_dn = os.environ.get('LDAPAUTHENTICATOR_USE_SSL') == 'True'
c.LDAPAuthenticator.user_search_base = os.environ.get('LDAPAUTHENTICATOR_USER_SEARCH_BASE')
c.LDAPAuthenticator.user_attribute = os.environ.get('LDAPAUTHENTICATOR_USER_ATTRIBUTE')
c.LDAPAuthenticator.use_ssl = os.environ.get('LDAPAUTHENTICATOR_USE_SSL') == 'True'
c.LDAPAuthenticator.allowed_groups = allowedgroups = []
pwd = os.path.dirname(__file__)
with open(os.path.join(pwd, 'allowedLDAPGroups')) as f:
for line in f:
if not line:
continue
allowedgroups.append(line)
c.LDAPAuthenticator.bind_dn_template = bindDnTemplate = []
pwd = os.path.dirname(__file__)
with open(os.path.join(pwd, 'bindDnTemplate')) as f:
for line in f:
if not line:
continue
bindDnTemplate.append(line)
The juypterhub_config.py
of my project uses the above shown LDAPAuthenticator configuration. If you are interested in which purpose each property has please visit the LDAP Authenticator Github page.
This repo uses the SwarmSpawner to create Notebook Servers as Docker Services in the Docker Swarm network.
c.SwarmSpawner.start_timeout = 60 * 60
c.SwarmSpawner.jupyterhub_service_name = os.environ.get('SWARMSPAWNER_HUB_SERVICE_NAME')
c.SwarmSpawner.service_prefix = os.environ.get('SWARMSPAWNER_SERVICE_PREFIX')
c.SwarmSpawner.networks = [os.environ.get('SWARMSPAWNER_NETWORK')]
c.SwarmSpawner.notebook_dir = os.environ.get('SWARMSPAWNER_NOTEBOOK_DIR')
c.SwarmSpawner.teachers = [os.environ.get('SWARMSPAWNER_TEACHERS')]
c.SwarmSpawner.teacher_image = os.environ.get('SWARMSPAWNER_TNOTEBOOK_IMAGE')
c.SwarmSpawner.student_image = os.environ.get('SWARMSPAWNER_SNOTEBOOK_IMAGE')
mounts = [{'type' : 'volume',
'target' : os.environ.get('SWARMSPAWNER_NOTEBOOK_DIR'),
'source' : 'jupyterhub-user-{username}',
'no_copy' : True,
'driver_config' : {
'name' : 'local',
'options' : {
'type' : 'nfs4',
'o' : 'addr='+os.environ.get('NFSSERVER_IP')+',rw',
'device' : ':'+os.environ.get('NFSSERVER_USERDATA_DEVICE')
}
}},{
'type' : 'volume',
'target' : '/srv/nbgrader/exchange',
'source' : 'jupyter-exchange-volume',
'no_copy' : True,
'driver_config' : {
'name' : 'local',
'options' : {
'type' : 'nfs4',
'o' : 'addr='+os.environ.get('NFSSERVER_IP')+',rw',
'device' : ':'+os.environ.get('NFSSERVER_ASSIGNMENTDATA_DEVICE')
}
}}]
c.SwarmSpawner.container_spec = {
'args' : ['start-singleuser.sh'],
'Image' : os.environ.get('SWARMSPAWNER_NOTEBOOK_IMAGE'),
'mounts' : mounts
}
c.SwarmSpawner.resource_spec = {}
The specific spawner configuration shown above is used in this repo to create Juypter Notebook Servers as Docker Services.
One may notice the config properties c.SwarmSpawner.teachers
, c.SwarmSpawner.teacher_image
and c.SwarmSpawner.student_image
are not available in the original repo. I forked the repo to add these properties, to checkout if the username, which is trying to spawn a new Server, is a teacher or a student. My DockerSwarmSpawner then uses different Docker Images for the Notebook Server. This feature is needed if one wants to use nbgrader
in the setup. A detailed explanation is NOT YET available on the wiki page DockerSwarmSpawner - nbgrader. You also may look to the page Docker Volumes to understand the mount
property of the config file.
You may ask your self, why the config uses that many ENV Variables. Well, after building the Jupyterhub Dockerimage, the jupyterhub_config.py
file can not be modified that easy. One may think, why not use a Docker Bind Volume, where the config file just be mounted before the service starts. I personally think, that this would be a quick and dirty way to perform changes of the Jupyterhub Config, but with ENV Variables the same result can be achieved. Either way you have to restart the service to make your config changes working.
You also may noticed that c.LDAPAuthenticator.allowed_groups
,c.LDAPAuthenticator.bind_dn_template
and c.Authenticator.admin_users
don't use ENV Variables. The reason for this is, that these properties need an array type to work correctly and after a quick research one will notice, that providing an array as a ENV Variable isn't that easy. ENV Variables are always interpreted as Strings. Furthermore, you can't define multiline ENV Variables, which makes the .env
file confusing to read/modify.