2025-10-16 20:48:35 +02:00
2025-10-16 20:48:35 +02:00
2025-10-16 20:48:35 +02:00
2025-10-16 20:48:35 +02:00
2025-10-16 20:48:35 +02:00
2025-10-16 20:48:35 +02:00
2025-10-16 20:48:35 +02:00
2025-10-16 20:48:35 +02:00

JupyterHub Configuration with OrbStack on Mac (all in Docker)

Prerequisites

You must have docker running on your computer

Installation Steps

1. Create Directory Structure

git clone https://forge.metabarcoding.org/MetabarcodingSchool/OBIJupyterHub.git

Enter into the OBIJupyterHub directory

cd OBIJupyterHub

File Structure

Your OBIJupyterHub directory should contain:

OBIJupyterHub
├── start-jupyterhub.sh                  - The script used to setup and start the server
├── obijupyterhub                        - The files describing the docker images and the stack
│   ├── Caddyfile
│   ├── docker-compose.yml
│   ├── Dockerfile
│   ├── Dockerfile.hub
│   ├── jupyterhub_config.py
│   ├── sftpgo_config.json
│   └── start-notebook.sh
├── jupyterhub_volumes                   - The directory containing the docker volumes
│   ├── caddy
│   ├── course                           - Read only volume mounted on every student container
│   │   ├── bin
│   │   └── R_packages
│   ├── jupyterhub
│   ├── shared                           - Read write volume shared in every student container
│   ├── users
│   └── web
│       ├── img
│       │   └── welcome_metabar.webp
│       ├── index.html
│       └── pages
├── Readme.md                            - This documentation
├── tools
│   ├── generate_pages_json.py
│   └── install_packages.sh
└─── web_src                             - The quarto document sources used to build the web site
    ├── _output
    ├── _quarto.yml
    ├── 00_home.qmd
    ├── lectures
    │   └── computers
    │       └── regex
    │           ├── lecture_regex.qmd
    │           ├── slides_regex.qmd
    │           └── slides.css
    └── scripts
         └── copy-to-web.sh

2. Start JupyterHub

From the terminal, in the OBIJupyterHub directory, run the following command:

./start-jupyterhub.sh

3. Access JupyterHub

Open your browser and go to: http://localhost:8888

You can log in as a student with any username and password: metabar2025

Useful Commands

View JupyterHub logs

cd obijupyterhub
docker-compose logs -f jupyterhub

View all containers (hub + students)

docker ps | grep jupyterhub

Stop JupyterHub

cd obijupyterhub
docker-compose down

Restart JupyterHub (after config modification)

cd obijupyterhub
docker-compose restart jupyterhub

View logs for a specific student

docker logs jupyter-<username>

Replace <username> by the actual username of the student.

Clean up after lab

# Stop and remove all containers
cd obijupyterhub
docker-compose down

# Remove student containers
docker ps -a | grep jupyter- | awk '{print $1}' | xargs docker rm -f

# Remove volumes (WARNING: deletes student data)
docker volume ls | grep jupyterhub-user | awk '{print $2}' | xargs docker volume rm

# Clean everything (containers + volumes + network)
docker-compose down -v
docker ps -a | grep jupyter- | awk '{print $1}' | xargs docker rm -f
docker volume prune -f

Managing Shared Data

Directory Structure for Each Student

Each student will see this directory structure in their JupyterLab (everything under work/ is persistent):

work/                             # Personal workspace root (persistent)
├── [student files]               # Their own files and notebooks
├── R_packages/                   # Personal R packages (writable by student)
├── shared/                       # Shared workspace (read/write, shared with all)
└── course/                       # Course files (read-only, managed by admin)
    ├── R_packages/               # Shared R packages (read-only, installed by prof)
    ├── bin/                      # Shared executables (in PATH)
    └── [course materials]        # Your course files

R Package Priority:

  1. R checks work/R_packages/ first (personal, writable)
  2. Then work/course/R_packages/ (shared, read-only, installed by prof)
  3. Then system libraries

Important: Everything is under work/, so all student files are automatically saved in their persistent volume.

User Accounts

Admin Account:

  • Username: admin
  • Password: admin2025 (change in docker-compose.yml: JUPYTERHUB_ADMIN_PASSWORD)
  • Can write to course/ directory

Student Accounts:

  • Username: any name
  • Password: metabar2025 (change in docker-compose.yml: JUPYTERHUB_PASSWORD)
  • Read-only access to course/ directory

Installing R Packages (Admin Only)

From your Mac (recommended):

# Install packages
tools/install_packages.sh reshape2 plotly knitr

This script: - Installs packages in the course/R_packages/ directory - All students can use them (read-only) - No need to rebuild the image

Students can also install their own packages:

Students can install packages in their personal work/R_packages/:

# Install in personal library (each student has their own)
install.packages('mypackage')  # Will install in work/R_packages/

Using R Packages (Students)

Students simply load packages normally:

library(reshape2)  # R checks: 1) work/R_packages/ 2) work/course/R_packages/ 3) system
library(plotly)

R automatically searches in this order:

  1. Personal packages: /home/jovyan/work/R_packages/ (R_LIBS_USER)
  2. Prof packages: /home/jovyan/work/course/R_packages/ (R_LIBS_SITE)
  3. System packages

List Available Packages

# List all available packages (personal + course + system)
installed.packages()[,"Package"]

# Check personal packages
list.files("/home/jovyan/work/R_packages")

# Check course packages (installed by prof)
list.files("/home/jovyan/work/course/R_packages")

Deposit Files for Course

To put files in the course/ directory (accessible read-only):

# Create a temporary directory
mkdir -p ~/jupyterhub-tp/course-files

# Copy your files into it
cp my_notebooks.ipynb ~/jupyterhub-tp/course-files/
cp my_data.csv ~/jupyterhub-tp/course-files/

# Copy into Docker volume
docker run --rm \
  -v jupyterhub-course:/target \
  -v ~/jupyterhub-tp/course-files:/source \
  alpine sh -c "cp -r /source/* /target/"

Retrieve Student Work

# List user volumes
docker volume ls | grep 'obijupyterhub_user-'

# Copy files from a specific student
docker run --rm \
  -v obijupyterhub_user-alice:/source \
  -v ~/submissions:/target \
  alpine sh -c "cp -r /source/* /target/alice/"

# Copy all shared work
docker run --rm \
  -v obijupyterhub_shared:/source \
  -v ~/submissions/shared:/target \
  alpine sh -c "cp -r /source/* /target/"

User Management

Option 1: Predefined User List

In jupyterhub_config.py, uncomment and modify:

c.Authenticator.allowed_users = {'student1', 'student2', 'student3'}

Option 2: Allow Everyone (for testing)

By default, the configuration allows any user:

c.Authenticator.allow_all = True

⚠️ Warning: DummyAuthenticator is ONLY for local testing!

Kernel Verification

Once logged in, create a new notebook and verify you have access to:

  • Python 3 (default kernel)
  • R (R kernel)
  • Bash (bash kernel)

Customization for Your Labs

Add Additional R Packages

Modify the Dockerfile (before USER ${NB_UID}):

RUN R -e "install.packages(c('your_package'), repos='http://cran.rstudio.com/')"

Then restart the server (it rebuilds the images if needed):

./start-jupyterhub.sh

Add Python Packages

Add to the Dockerfile (before USER ${NB_UID}):

RUN pip install numpy pandas matplotlib seaborn

Distribute Files to Students

Create a files_lab/ directory and add to the Dockerfile:

COPY files_lab/ /home/${NB_USER}/lab/
RUN chown -R ${NB_UID}:${NB_GID} /home/${NB_USER}/lab

Change Port (if 8000 is occupied)

Modify in docker-compose.yml:

ports:
  - "8001:8000"  # Accessible on localhost:8001

Advantages of This Approach

Everything in Docker: No need to install Python/JupyterHub on your computer
Portable: Easy to deploy on another server
Isolated: No pollution of your system environment
Easy to Clean: A simple docker-compose down is enough
Reproducible: Students will have exactly the same environment

Troubleshooting

Error "Cannot connect to Docker daemon":

  • Check that OrbStack is running
  • Verify the socket exists: ls -la /var/run/docker.sock

Student containers don't start:

  • Check logs: docker-compose logs jupyterhub
  • Verify student image exists: docker images | grep jupyterhub-student

Port 8000 already in use:

  • Change port in docker-compose.yml

I want to start from scratch:

push obijupyterhub
docker-compose down -v
docker rmi jupyterhub-hub jupyterhub-student
popd

# Then rebuild everything
./start-jupyterhub.sh
Description
No description provided
Readme 306 KiB
Languages
Shell 32.6%
Python 32.2%
HTML 25.2%
Dockerfile 9.3%
CSS 0.7%