diff --git a/Dockerfile.jupyterhub b/Dockerfile.jupyterhub index d88b9cd..afb3125 100755 --- a/Dockerfile.jupyterhub +++ b/Dockerfile.jupyterhub @@ -8,8 +8,14 @@ RUN /opt/conda/bin/conda install -yq psycopg2=2.7 && \ /opt/conda/bin/conda clean -tipsy && \ /opt/conda/bin/pip install --no-cache-dir \ oauthenticator==0.8.* +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + vim -RUN pip install jupyterhub-hashauthenticator git+https://github.com/jupyterhub/dockerspawner.git@master +RUN apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +RUN pip install jupyterhub-hashauthenticator dockerspawner==0.10.0 # Copy TLS certificate and key #ENV SSL_CERT /srv/jupyterhub/secrets/jupyterhub.crt diff --git a/groups.sh b/groups.sh new file mode 100755 index 0000000..1a1f07d --- /dev/null +++ b/groups.sh @@ -0,0 +1,8 @@ +#!/bin/bash +source .env +NUM_GROUPS=4 +for i in `seq 1 $NUM_GROUPS`; do + docker volume create shared-$HUB_NAME-group$i + sudo chmod 777 $(docker inspect shared-$HUB_NAME-group$i | grep "Mountpoint" | awk '{print $2}' | sed 's/"//g' | sed 's/,//g') +done + diff --git a/jupyterhub_config.py b/jupyterhub_config.py index c60ef6d..24ea8e1 100755 --- a/jupyterhub_config.py +++ b/jupyterhub_config.py @@ -1,5 +1,6 @@ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. +# Major edits by MathematicalMichael(.com) 02-2019 # Configuration file for JupyterHub import os @@ -32,20 +33,26 @@ class MyDockerSpawner(DockerSpawner): for i in range(1,len(parts)): group_id = parts.pop() - if group_id != 'admin': # no need for an admin group. - group_map[user_name].append(group_id) + group_map[user_name].append(group_id) def start(self): if self.user.name in self.group_map: group_list = self.group_map[self.user.name] # add team volume to volumes - for group_id in group_list: - self.volumes['shared-{}'.format(group_id)] = { - 'bind': '/home/jovyan/%s'%(group_id), - 'mode': 'rw', # or ro for read-only - } - if self.user.name == 'hub-admin': # if admin, allow userlist access - self.volumes[os.path.join(pwd,'userlist')] = { 'bind': '/home/jovyan/userlist', - 'mode': 'rw' } + for group_id in group_list: # admins in userlist get to write files. + if group_id != 'admin': + if 'admin' in group_list: + self.volumes['shared-{}'.format(group_id)] = \ + { 'bind': '/home/jovyan/%s'%(group_id), + 'mode': 'rw' } # or ro for read-only + else: # this "shared-" is part of the naming convention + self.volumes['shared-{}'.format(group_id)] = \ + {'bind': '/home/jovyan/%s'%(group_id), + 'mode': 'ro' } # or rw for write (can cause conflicts) + else: # if admin is one of the groups in userlist, mount the following: + self.volumes['%s/userlist'%(os.environ['HUB_LOC'])] = \ + { 'bind': '/home/jovyan/userlist', 'mode': 'rw' } + self.volumes['%s/jupyterhub_config.py'%(os.environ['HUB_LOC'])] = \ + { 'bind': '/home/jovyan/jupyterhub_config.py', 'mode': 'rw' } self.environment['JUPYTER_ENABLE_LAB'] = 'yes' return super().start() @@ -75,7 +82,7 @@ spawn_cmd = os.environ.get('DOCKER_SPAWN_CMD', "start-singleuser.sh") c.DockerSpawner.extra_create_kwargs.update({ 'command': spawn_cmd }) # Memory limit -c.Spawner.mem_limit = '2G' # RAM limit +c.Spawner.mem_limit = '4G' # RAM limit c.Spawner.cpu_limit = 0.0001 # Connect containers to this Docker network diff --git a/makefile b/makefile index 1c9149c..2b2536a 100755 --- a/makefile +++ b/makefile @@ -17,7 +17,7 @@ secrets/postgres.env: @echo "POSTGRES_PASSWORD=$(shell openssl rand -hex 32)" > $@ secrets/oauth.env: - @echo "Generating postgres password in $@" + @echo "Generating hash key in $@" @echo "HASH_SECRET_KEY=$(shell openssl rand -hex 32)" > $@ login: diff --git a/setup.sh b/setup.sh index 892b3a4..e052792 100755 --- a/setup.sh +++ b/setup.sh @@ -3,10 +3,17 @@ # this script is meant to be run only the first time a hub is being set up. # create a default userlist -echo "hub-admin admin shared" > userlist +# Use the format \"studentname HUB_NAME-group1\" on each line to add students to groups (10 by default have already been created and permissions appropriately set)" +echo "hub-admin admin shared" >> userlist + +# change permissions so that admins can edit these. +sudo chmod 777 userlist +sudo chmod 777 jupyterhub_config.py + mkdir secrets make secrets/oauth.env make secrets/postgres.env +echo "HUB_LOC=$(pwd)" >> .env source .env # show what is needed to be added to /etc/nginx/sites-enabled/hub.conf @@ -19,7 +26,7 @@ docker-compose up -d echo -en "\n\nWe create a default shared volume and set its permissions to be read/write. You may have to enter your password now:\n" docker volume create shared-shared sudo chmod 777 $(docker inspect shared-shared | grep "Mountpoint" | awk '{print $2}' | sed 's/"//g' | sed 's/,//g') -echo -en "Volume has been created." +echo -en "Globally shared volume has been created." echo -en "\n\nHub has been launched. Here are the Docker processes running right now:" docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" diff --git a/singleuser/Dockerfile b/singleuser/Dockerfile index 49b436b..2210804 100755 --- a/singleuser/Dockerfile +++ b/singleuser/Dockerfile @@ -1,7 +1,9 @@ ARG DOCKER_NOTEBOOK_IMAGE +ARG DISPLAY FROM $DOCKER_NOTEBOOK_IMAGE ARG JUPYTERHUB_VERSION #any additional installations go here. +RUN export DISPLAY=$DISPLAY USER root @@ -12,27 +14,45 @@ RUN apt-get update && \ fonts-dejavu \ tzdata \ gfortran \ - gcc && \ - rm -rf /var/lib/apt/lists/* + gcc + +# finish off with MPI dependencies (only required if not installing fenics) +#RUN sudo apt-get install mpich libmpich-dev -y +RUN rm -rf /var/lib/apt/lists/* USER jovyan +RUN conda update --all +RUN conda install fenics -RUN python3 -m pip install --no-cache jupyterhub==$JUPYTERHUB_VERSION nbresuse -RUN conda install -c conda-forge fenics - -RUN python3 -m pip install ipyparallel +# If you do not need parallelism, delete the following. +RUN python3 -m pip install ipyparallel mpi4py RUN ipython profile create --parallel --profile=mpi +RUN ipython profile create --parallel --profile=default RUN echo "c.IPClusterEngines.engine_launcher_class = 'MPIEngineSetLauncher'" >> /home/jovyan/.ipython/profile_mpi/ipcluster_config.py -RUN conda create --quiet --yes -p $CONDA_DIR/envs/python2 python=2.7 ipython ipykernel kernda numpy pandas matplotlib ipywidgets yaml +# Python 2 environment +RUN conda create --quiet --yes -p $CONDA_DIR/envs/python2 python=2.7 ipython ipykernel kernda numpy pandas matplotlib ipywidgets yaml ipyparallel mpi4py scipy pyDOE +RUN /opt/conda/envs/python2/bin/ipython profile create --parallel --profile=mpi USER root - # Create a global kernelspec in the image and modify it so that it properly activates # the python2 conda environment. RUN $CONDA_DIR/envs/python2/bin/python -m ipykernel install && \ $CONDA_DIR/envs/python2/bin/kernda -o -y /usr/local/share/jupyter/kernels/python2/kernel.json +USER $NB_UID +# Jupyterhub and memory monitoring +RUN python3 -m pip install --no-cache jupyterhub==$JUPYTERHUB_VERSION nbresuse && \ + jupyter labextension install jupyterlab-topbar-extension && \ + jupyter labextension install jupyterlab-system-monitor && \ + npm cache clean --force && \ + rm -rf $CONDA_DIR/share/jupyter/lab/staging && \ + rm -rf /home/$NB_USER/.cache/yarn && \ + rm -rf /home/$NB_USER/.node-gyp && \ + fix-permissions $CONDA_DIR && \ + fix-permissions /home/$NB_USER + +# R environment USER root RUN apt-get update && \ @@ -63,6 +83,7 @@ ENV PATH="${PATH}:/usr/lib/rstudio-server/bin" ENV LD_LIBRARY_PATH="/usr/lib/R/lib:/lib:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/amd64/server:/opt/conda/lib/R/lib" #ENV LD_LIBRARY_PATH="/usr/lib/R/lib:/lib:/usr/lib/x86_64-linux-gnu:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/amd64/server:/opt/conda/lib/R/lib" + +# USER SETTINGS USER jovyan RUN echo "export EDITOR=/usr/bin/vim" >> /home/jovyan/.bashrc -RUN echo "source /home/jovyan/work/.bash_custom" >> /home/jovyan/.bashrc