Skip to content

DurhamARC/jupyterhub-eosc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

JupyterHub on EOSC — Ansible Configuration

Ansible playbooks for provisioning a JupyterHub instance on an EOSC EU Node (PSNC OpenStack) VM.

JupyterHub runs containerised via Docker Compose, with per-user datascience-notebook containers spawned by DockerSpawner, behind an nginx reverse proxy with Let's Encrypt TLS.

Before running the playbooks, the VM must be provisioned and networked on OpenStack. Two options:

  • Manual: follow eosc-vm-setup.md step by step via the Horizon dashboard.
  • Automated: run provision_vm.yaml using OpenStack's Mistral workflow service. Edit the input defaults at the top of the file (instance name, flavour, network names, keypair) then execute via the Mistral CLI or Horizon. The workflow handles network, subnet, router, instance launch, and floating IP association in sequence, and outputs the assigned floating IP for use in inventory/hosts.yml.

Requirements

On your local machine:

  • Ansible ≥ 2.14
  • community.docker collection:
    ansible-galaxy collection install community.docker

On the EOSC VM:

  • Ubuntu 24.04, floating IP assigned
  • Security group with ingress on TCP 22, 80, and 443
  • A domain name resolving to the floating IP (required for Let's Encrypt)

Configuration

Edit inventory/hosts.yml and fill in:

Key Description
ansible_host Floating IP of the VM
server_domain Domain name resolving to the floating IP
letsencrypt_email Contact email for Let's Encrypt

Key variables (with defaults in group_vars/all.yml):

Variable Default Description
primary_user ubuntu SSH user on the VM
jupyterhub_admin_user admin First JupyterHub admin account
jupyterhub_notebook_image quay.io/jupyter/datascience-notebook:latest Image spawned per user
jupyterhub_docker_network jupyterhub_network Docker network name
jupyterhub_user_mem_limit 8G Per-user notebook container memory limit (c.DockerSpawner.mem_limit)
jupyterhub_user_cpu_limit 4 Per-user notebook container CPU limit (c.DockerSpawner.cpu_limit)

Usage

Initial setup

ansible-playbook playbooks/setup-server.yml

Roles applied in order:

Role What it does
users Ensures ubuntu is in the docker group; optionally copies authorized_keys
system Upgrades packages, installs Docker CE + Compose plugin
security fail2ban SSH jail, disables root login and password auth
nginx Installs nginx, obtains Let's Encrypt cert, configures HTTPS reverse proxy
jupyterhub Builds hub image, deploys Docker Compose stack

Run a subset of roles with --tags, e.g.:

ansible-playbook playbooks/setup-server.yml --tags nginx,jupyterhub

First login

  1. Go to https://<server_domain>/hub/signup
  2. Create the admin account (or whatever jupyterhub_admin_user is set to)
  3. Log in — the admin account is pre-authorised and does not require approval
  4. Approve other users at /hub/authorize

Redeploy JupyterHub

After config or Dockerfile changes:

# Rebuild image and restart — preserves user accounts
ansible-playbook playbooks/redeploy-jupyterhub.yml

# Full wipe — resets user database (use if locked out)
ansible-playbook playbooks/redeploy-jupyterhub.yml -e wipe_state=true

Repository structure

ansible.cfg                   Ansible defaults and SSH settings
inventory/hosts.yml           Target host and variables (fill in before use)
group_vars/all.yml            Variable defaults
playbooks/
  setup-server.yml            Full server provisioning
  redeploy-jupyterhub.yml     Rebuild and restart JupyterHub only
roles/
  users/                      SSH key deployment, docker group membership
  system/                     Package upgrades, Docker CE installation
  security/                   fail2ban, SSH hardening
  nginx/                      nginx + Let's Encrypt TLS
  jupyterhub/                 JupyterHub Docker Compose stack
provision_vm.yaml             Mistral workflow for OpenStack VM provisioning
eosc-vm-setup.md              Manual VM setup guide for EOSC/PSNC OpenStack

JupyterHub architecture

Internet → nginx (:443 TLS) → localhost:8000 → jupyterhub container
                                                      ↓ DockerSpawner
                                               per-user notebook containers
                                               (on jupyterhub_network)
  • Hub state (user DB, cookie secret) persists in Docker volume jupyterhub_jupyterhub_data
  • Per-user work directories persist in volumes named jupyterhub-user-<username>
  • The hub container has read-only access to /var/run/docker.sock to spawn user containers

Updating the notebook image

Change jupyterhub_notebook_image in inventory/hosts.yml and run:

ansible-playbook playbooks/redeploy-jupyterhub.yml

Existing user volumes are preserved; new image takes effect on next server spawn.

About

Ansible playbooks and Mistral workflow for deploying a shared JupyterHub on the EOSC EU Node (PSNC OpenStack)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors