This cookbook installs JupyterHub a multi-user Hub which spawns, manages, and proxies multiple instances of the single-user Jupyter notebook server.
By default Python2 and Python36 are installed from system package repos. A different Python package, or additional pips, can be specified for installation by overriding the following attributes.
# python
node['python']['python2']['packages'] = %w(python-devel python2-pip python-setuptools)
node['python']['python2']['bin'] = '/bin/python2'
node['python']['python2']'pip_bin'] = '/bin/pip2'
node['python']['python2']['pips'] = %w()
node['python']['python3']['packages'] = %w(python3-devel python3-pip python3-setuptools)
node['python']['python3']['bin'] = '/bin/python3.6'
node['python']['python3']'pip_bin'] = '/bin/pip3.6'
node['python']['python3']['pips'] = %w('notebook<6' jupyter py4j ipyparallel)The current 6.x version of NodeJS is installed by default. A different version of NodeJS, or additional npms, can be specified for installation by overriding the following attributes.
# node
node['nodejs']['version'] = '6.x'
node['nodejs']['npms'] = %w()
node['nodejs']['global_npms'] = %w(npm configurable-http-proxy)By default this cookbook installs JupyterHub version 0.9.4, which at the time of this writing, is the current version. Various changes can be made to JupyterHub's configuration by overriding the following attributes.
# jupyterhub
node['jupyterhub']['install_from'] = 'python'
node['jupyterhub']['install_version'] = '0.9.6'
node['jupyterhub']['setup']['run_as'] = 'root'
node['jupyterhub']['setup']['pid_file'] = '/var/run/jupyter.pid'
node['jupyterhub']['setup']['app_dir'] = '/opt/jupyterhub'
node['jupyterhub']['setup']['runtime_dir'] = '/srv/jupyterhub'
node['jupyterhub']['setup']['log_dir'] = '/var/log/jupyterhub'
node['jupyterhub']['setup']['enable_ssl'] = false
node['jupyterhub']['setup']['enable_ldap'] = false
node['jupyterhub']['config']['jupyterhub_config'][
node['jupyterhub']['config']['jupyterhub_config']['JupyterHub.ip'] = ''
node['jupyterhub']['config']['jupyterhub_config']['JupyterHub.port'] = '8000'
node['jupyterhub']['config']['jupyterhub_config']['JupyterHub.ssl_port'] = '8443'
node['jupyterhub']['config']['jupyterhub_config']['JupyterHub.hub_ip'] = '127.0.0.1'
node['jupyterhub']['config']['jupyterhub_config']['JupyterHub.hub_port'] = '8081'
node['jupyterhub']['config']['jupyterhub_config']['JupyterHub.proxy_api_ip'] = '127.0.0.1'
node['jupyterhub']['config']['jupyterhub_config']['JupyterHub.proxy_api_port'] = '8001'
node['jupyterhub']['config']['jupyterhub_config']['JupyterHub.ssl_cert'] = '/etc/ssl/certs/jupyterhub.crt'
node['jupyterhub']['config']['jupyterhub_config']['JupyterHub.ssl_key'] = '/etc/ssl/private/jupyterhub.key'
node['jupyterhub']['config']['jupyterhub_config']['Authenticator.whitelist'] = %w()
node['jupyterhub']['config']['jupyterhub_config']['Authenticator.admin_users'] = %w()
node['jupyterhub']['config']['jupyterhub_config']['JupyterHub.authenticator_class'] = 'jupyterhub.auth.PAMAuthenticator'
node['jupyterhub']['config']['jupyterhub_config']['Spawner.cmd'] = 'jupyterhub-singleuser'
node['jupyterhub']['config']['jupyterhub_config']['Spawner.args'] = '--NotebookApp.allow_remote_access=True'
node['jupyterhub']['config']['jupyterhub_config']['Spawner.notebook_dir'] = '~/jupyterhub'All system users with login rights will be allowed to log into JupyterHub. This scope can be narrowed by modifying the following attributes.
# permissions
node['jupyterhub']['config']['jupyterhub_config']['Authenticator.whitelist'] = %w()
node['jupyterhub']['config']['jupyterhub_config']['Authenticator.admin_users'] = %w()LDAP Authentication is not provided in Jupyterhub out of the box. This functionality is provided by the jupyterhub-ldap-authenticator package which is installed by default with this cookbook. To utilize this package and enable LDAP Authentication, define the following keys in your attributes file.
# enable ldap
node['jupyterhub']['config']['enable_ldap'] = true
node['jupyterhub']['config']['jupyterhub_config']['JupyterHub.authenticator_ldap_class'] = 'ldapauthenticator.LDAPAuthenticator'
node['jupyterhub']['config']['jupyterhub_config']['LDAPAuthenticator.server_hosts'] = %w(ldaps://ldap1.example.com:636 ldaps://ldap2.example.com:636)
node['jupyterhub']['config']['jupyterhub_config']['LDAPAuthenticator.bind_user_dn'] = 'uid=imauser,cn=users,cn=accounts,dc=example,dc=com'
node['jupyterhub']['config']['jupyterhub_config']['LDAPAuthenticator.bind_user_password'] = 'imapassword'
node['jupyterhub']['config']['jupyterhub_config']['LDAPAuthenticator.user_search_base'] = 'cn=users,cn=accounts,dc=example,dc=com'
node['jupyterhub']['config']['jupyterhub_config']['LDAPAuthenticator.user_search_filter'] = '(&(objectClass=person)(uid={username}))'
node['jupyterhub']['config']['jupyterhub_config']['LDAPAuthenticator.user_membership_attribute'] = 'memberOf'
node['jupyterhub']['config']['jupyterhub_config']['LDAPAuthenticator.group_search_base'] = 'cn=groups,cn=accounts,dc=example,dc=com'
node['jupyterhub']['config']['jupyterhub_config']['LDAPAuthenticator.group_search_filter'] = '(&(objectClass=ipausergroup)(memberOf={group}))'
node['jupyterhub']['config']['jupyterhub_config']['LDAPAuthenticator.allowed_groups'] = %w(cn=jupyterhub-users,cn=groups,cn=accounts,dc=example,dc=com)
node['jupyterhub']['config']['jupyterhub_config']['LDAPAuthenticator.allow_nested_groups'] = 'True'
node['jupyterhub']['config']['jupyterhub_config']['LDAPAuthenticator.create_user_home_dir'] = 'True'
node['jupyterhub']['config']['jupyterhub_config']['LDAPAuthenticator.create_user_home_dir_cmd'] = %w(mkhomedir_helper)By default Jupyterhub uses a SQLite database. To use PostgreSQL instead, configure your postgresql server and then add the following keys to your attribute file. Replace values with those associated to your specific instance.
node['jupyterhub']['db']['type'] = 'postgresql'
node['jupyterhub']['db']['user'] = 'jupyterhub_db_user'
node['jupyterhub']['db']['pass'] = 'jupyterhub_db_pass'
node['jupyterhub']['db']['host'] = 'jupyterhub_db_server'
node['jupyterhub']['db']['port'] = '5432'
node['jupyterhub']['db']['name'] = 'jupyterhub_db_name'The IPython kernel is the Python execution backend for Jupyter/JupyterHub. This cookbook includes 4 kernels by default, they are as follows:
- python2: kernel running native python
2.7 - python3: kernel running native python
3.6 - anaconda2: kernel running python
2.7.15and default anaconda packages - anaconda3: kernel running python
3.6.5and default anaconda packages
These kernels can be enabled/disabled as desired. The kernel name, python version, and included pips/condas can also be changed by modifying the following attributes.
# python
node['python']['virtualenvs']['python2']['dest_dir'] = '/opt/python/virtualenv/python2'
node['python']['virtualenvs']['python2']['python'] = '/bin/python2'
node['python']['virtualenvs']['python2']['pips'] = %w(boto3 csvkit ipykernel Keras nose nose-parameterized pandas pyGPs requests tensorflow Theano)
node['python']['virtualenvs']['python3']['dest_dir'] = '/opt/python/virtualenv/python3'
node['python']['virtualenvs']['python3']['python'] = '/bin/python3.6'
node['python']['virtualenvs']['python3']['pips'] = %w(boto3 csvkit ipykernel Keras nose nose-parameterized pandas pyGPs requests tensorflow Theano)
# anaconda
node['anaconda']['virtualenvs']['anaconda2']['python'] = '2.7.15'
node['anaconda']['virtualenvs']['anaconda2']['condas'] = %w(numpy pandas)
node['anaconda']['virtualenvs']['anaconda2']['pips'] = %w(ipykernel)
node['anaconda']['virtualenvs']['anaconda3']['python'] = '3.6.5'
node['anaconda']['virtualenvs']['anaconda3']['condas'] = %w(numpy pandas)
node['anaconda']['virtualenvs']['anaconda3']['pips'] = %w(ipykernel)
# jupyter kernels(s)
node['jupyter']['kernels']['python2']['displayname'] = 'Python 2'
node['jupyter']['kernels']['python2']['install'] = true
node['jupyter']['kernels']['python2']['python_dist'] = 'python'
node['jupyter']['kernels']['python2']['python_env'] = 'python2'
node['jupyter']['kernels']['python3']['displayname'] = 'Python 3'
node['jupyter']['kernels']['python3']['install'] = true
node['jupyter']['kernels']['python3']['python_dist'] = 'python'
node['jupyter']['kernels']['python3']['python_env'] = 'python3'
node['jupyter']['kernels']['anaconda2']['displayname'] = 'Anaconda 2'
node['jupyter']['kernels']['anaconda2']['install'] = true
node['jupyter']['kernels']['anaconda2']['python_dist'] = 'anaconda'
node['jupyter']['kernels']['anaconda2']['python_env'] = 'anaconda2'
node['jupyter']['kernels']['anaconda3']['displayname'] = 'Anaconda 3'
node['jupyter']['kernels']['anaconda3']['install'] = true
node['jupyter']['kernels']['anaconda3']['python_dist'] = 'anaconda'
node['jupyter']['kernels']['anaconda3']['python_env'] = 'anaconda3'To create your own custom kernel with a pinned version of python and specific included packages include the following in your attributes file. Replace python-custom with the desired name of your kernel.
# custom anaconda kernel
node['anaconda']['virtualenvs']['python-custom']['python'] = '3.6.5'
node['anaconda']['virtualenvs']['python-custom']['condas'] = %w(numpy pandas)
node['anaconda']['virtualenvs']['python-custom']['pips'] = %w(ipykernel matplotlib scikit-learn tensorflow)
node['jupyter']['kernels']['python-custom']['displayname'] = 'Python Custom'
node['jupyter']['kernels']['python-custom']['install'] = true
node['jupyter']['kernels']['python-custom']['python_dist'] = 'anaconda'
node['jupyter']['kernels']['python-custom']['python_env'] = 'python-custom'Once installed JupyterHub is available at http://127.0.0.1:8000 unless otherwise modified using the attributes referenced above. Before a user can log into JupyterHub he/she must create their notebooks directory at ~/jupyterhub. Failure to create this directory will result in 500 errors when logging in.
The following resources may be helpful to better understand JupyterHub usage: