---
tags: CCNS, python, conda, jupyter
---
JupyterHub + LDAPAuth + DockerSpawner Installation note
===
OS
---
```
Ubuntu Server 18.04.5
```
Install CUDA
---
https://developer.nvidia.com/cuda-downloads?
https://www.tensorflow.org/install/gpu
```bash
# Add NVIDIA package repositories
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-repo-ubuntu1804_10.0.130-1_amd64.deb
sudo dpkg -i cuda-repo-ubuntu1804_10.0.130-1_amd64.deb
sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub
sudo apt-get update
wget http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/nvidia-machine-learning-repo-ubuntu1804_1.0.0-1_amd64.deb
sudo apt install ./nvidia-machine-learning-repo-ubuntu1804_1.0.0-1_amd64.deb
sudo apt-get update
# Install NVIDIA driver
sudo apt-get install --no-install-recommends nvidia-driver-410
# Reboot. Check if GPUs are visible using the command: nvidia-smi
# Install development and runtime libraries (~4GB)
sudo apt-get install --no-install-recommends \
cuda-10-0 \
libcudnn7=7.4.1.5-1+cuda10.0 \
libcudnn7-dev=7.4.1.5-1+cuda10.0
```
Install Docker
---
https://cloud.tencent.com/developer/article/1011087
```bash
curl -fsSL https://get.docker.com/ | sh
```
Change Docker daemon directory
---
https://docs.docker.com/config/daemon/
```bash
sudo vim /etc/docker/daemon.json
```
```
{
"data-root": "/data/docker",
"runtimes": {
"nvidia": {
"path": "nvidia-container-runtime",
"runtimeArgs": []
}
}
}
```
Install nvidia-docker
---
https://github.com/NVIDIA/nvidia-docker
```bash
# Add the package repositories
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get update
# Install nvidia-docker2 and reload the Docker daemon configuration
sudo apt-get install -y nvidia-docker2
sudo systemctl restart docker
# Test nvidia-smi with the latest official CUDA image
docker run --rm --gpus all nvidia/cuda nvidia-smi
```
### Enable log file if needed
```
vim /etc/nvidia-container-runtime/config.toml ### Uncomment debug=...
```
Install conda
---
https://docs.anaconda.com/anaconda/install/linux/
```bash
wget https://repo.anaconda.com/archive/Anaconda3-2018.12-Linux-x86_64.sh
bash Anaconda3-2018.12-Linux-x86_64.sh
source ~/.bashrc
conda -V
```
Install Jupyter
---
https://jupyter.readthedocs.io/en/latest/install.html
No need if you have installed Anaconda in the previous setp.
Install JupyterHub
---
https://jupyterhub.readthedocs.io/en/stable/quickstart.html
```bash
conda install -c conda-forge jupyterhub # Install JupyterHub and proxy
conda install notebook # Needed if running notebook servers in local
jupyterhub -h
configurable-http-proxy -h
```
Config options
https://jupyterhub.readthedocs.io/en/stable/installation-basics.html
- Path suggestions
- `/srv/jupyterhub` for all security and runtime files
- `/etc/jupyterhub` for all configuration files
- `/var/log` for log files
- Config planning
- Deployment system (Bare metal, Docker)
- Authentication (PAM, OAuth, etc.)
- Spawner of singleuser notebook servers (Docker, Batch, etc.)
- Services (nbgrader, etc.)
- JupyterHub database (default SQLite; traditional RDBMS such as PostgreSQL,) MySQL, or other databases supported by SQLAlchemy)
Generate config file for JupyterHub
---
https://jupyterhub.readthedocs.io/en/stable/getting-started/config-basics.html
```bash
mkdir -p /etc/jupyterhub
cd /etc/jupyterhub
jupyterhub --generate-config
jupyterhub -f /etc/jupyterhub/jupyterhub_config.py
```
Config LDAP Authentication
---
https://jupyterhub.readthedocs.io/en/stable/reference/authenticators.html
https://github.com/jupyterhub/ldapauthenticator
```bash
conda install -c conda-forge jupyterhub-ldapauthenticator
```
Edit `/etc/jupyterhub/jupyterhub_config.py`
```
c.JupyterHub.authenticator_class = 'ldapauthenticator.LDAPAuthenticator'
c.LDAPAuthenticator.server_address = '<server_address>'
c.LDAPAuthenticator.bind_dn_template = 'uid={username},cn=users,dc=example,dc=com'
c.LDAPAuthenticator.use_ssl = True
```
Config Docker spawner
---
https://jupyterhub.readthedocs.io/en/stable/reference/spawners.html
https://github.com/jupyterhub/dockerspawner
```bash
conda install -c conda-forge dockerspawner
```
Edit `/etc/jupyterhub/jupyterhub_config.py`
```python
c.JupyterHub.spawner_class = 'dockerspawner.DockerSpawner'
c.DockerSpawner.image_whitelist = {
"deepdetect-gpu (Tensorflow+PyTorch)": "jolibrain/jupyter-dd-notebook-gpu",
"tensorflow-2-gpu (Tensorflow 2.0)": "d4n1el/tensorflow-2-notebook-gpu",
"datascience-gpu (Python+Julia+R)": "d4n1el/datascience-notebook-gpu",
"tensorflow-cpu (Tensorflow)": "jupyter/tensorflow-notebook",
"datascience-cpu (Python+Julia+R)": "jupyter/datascience-notebook",
}
c.DockerSpawner.remove_containers = True
c.DockerSpawner.extra_create_kwargs = {'user': 'root'}
c.DockerSpawner.extra_host_config = {'runtime': 'nvidia'}
c.Spawner.environment = {'GRANT_SUDO': 'yes'}
from jupyter_client.localinterfaces import public_ips
c.JupyterHub.hub_ip = public_ips()[0]
```
Good notebook image list
```
docker pull jupyter/tensorflow-notebook
docker pull jupyter/datascience-notebook
```
w/ GPU supports:
https://github.com/d4n1elchen/docker-stacks
```
docker pull jolibrain/jupyter-dd-notebook-gpu
docker pull d4n1el/tensorflow-2-notebook-gpu
docker pull d4n1el/datascience-notebook-gpu
docker run --runtime=nvidia --rm jolibrain/jupyter-dd-notebook-gpu nvidia-smi
```
Automatically add and mount remote folder for persistence data for each user and bind to the container
```python
import os, shutil
def create_dir_hook(spawner):
""" Create directory """
username = spawner.user.name # get the username
home_path = os.path.join('/home/', username)
volume_path = os.path.join(home_path, 'net')
net_path = os.path.join('/net/eugeo-home/', username)
if not os.path.exists(volume_path):
os.mkdir(home_path)
shutil.chown(home_path, user=username, group='users')
c.Spawner.pre_spawn_hook = create_dir_hook
c.DockerSpawner.volumes = { '/net/eugeo-home/{username}': '/home/{username}/net',
'/net/eugeo-home/{username}/sortiliena-home': '/home/{username}/net/sortiliena-home',
'/net/eugeo-home/{username}/yuuki-home': '/home/{username}/net/yuuki-home' }
```
[sftp Settings](https://hackmd.io/GkvAp8HMTMGhUTqELgf_pQ?both)
Config domain and ssl for jupyterhub
---
https://jupyterhub.readthedocs.io/en/stable/getting-started/security-basics.html
Sign a certificate
```
openssl req -x509 -nodes -days 3650 -newkey rsa:1024 -keyout /etc/jupyterhub/certificate/key.pem -out /etc/jupyterhub/certificate/cert.pem
```
Edit config
```python
c.JupyterHub.ssl_cert = '/etc/jupyterhub/certificate/cert.pem'
c.JupyterHub.ssl_key = '/etc/jupyterhub/certificate/key.pem'
```
Setup jupyterhub as system service
---
https://github.com/jupyterhub/jupyterhub/wiki/Run-jupyterhub-as-a-system-service
Add `/etc/systemd/system/jupyterhub.service`
```
[Unit]
Description=Jupyterhub
After=syslog.target network.target
[Service]
User=root
Environment="PATH=/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/anaconda3/bin"
ExecStart=/root/anaconda3/bin/jupyterhub -f /etc/jupyterhub/jupyterhub_config.py
[Install]
WantedBy=multi-user.target
```
```bash
sudo systemctl daemon-reload
sudo systemctl start jupyterhub
sudo systemctl status jupyterhub
sudo systemctl enable jupyterhub
```