diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c67bf3f --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/jupyterhub_volumes/users +/jupyterhub_volumes/shared +/jupyterhub_volumes/jupyterhub +/jupyterhub_volumes/caddy diff --git a/Caddyfile b/Caddyfile new file mode 100644 index 0000000..76435d2 --- /dev/null +++ b/Caddyfile @@ -0,0 +1,43 @@ +http:// { + + root * /srv + file_server + + # Proxy pour SFTPGo avec réécriture du chemin + # Proxy pour l'interface Web de SFTPGo + # SFTPGo n'a pas de support natif pour les sous-chemins + # Il faut proxy /web/ et /static/ séparément + handle /web/* { + reverse_proxy http://jupytersftp:8080 { + header_up X-Real-IP {remote_host} + header_up X-Forwarded-For {remote_host} + } + } + + handle /static/* { + reverse_proxy http://jupytersftp:8080 { + header_up X-Real-IP {remote_host} + header_up X-Forwarded-For {remote_host} + } + } + + handle /api/* { + reverse_proxy http://jupytersftp:8080 { + header_up X-Real-IP {remote_host} + header_up X-Forwarded-For {remote_host} + } + } + + handle /sftp/* { + uri strip_prefix /sftp + reverse_proxy http://jupytersftp:8080 { + header_up X-Real-IP {remote_host} + header_up X-Forwarded-For {remote_host} + } + } + + # Proxy vers JupyterHub + handle /jupyter/* { + reverse_proxy http://jupyterhub:8000 + } +} \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 6d22d71..ca15cd3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,9 +4,10 @@ services: context: . dockerfile: Dockerfile.hub container_name: jupyterhub + hostname: jupyterhub image: jupyterhub-hub:latest - ports: - - "8888:8000" + expose: + - "8000" volumes: # Access to Docker socket to spawn student containers - /var/run/docker.sock:/var/run/docker.sock @@ -25,6 +26,47 @@ services: # Optional environment variables DOCKER_NOTEBOOK_DIR: /home/jovyan/work + # ---------- Nginx ---------- + + caddy: + container_name: jupyterhub-caddy + hostname: jupytercaddy + image: caddy:latest + ports: + - "8888:80" + volumes: + - ./Caddyfile:/etc/caddy/Caddyfile + - jupyterhub-caddy-data:/data + - jupyterhub-caddy-config:/config + - jupyterhub-web:/srv # Votre app + networks: + - jupyterhub-network + restart: unless-stopped + + # ---------- SFTPGo ---------- + sftpgo: + image: drakkan/sftpgo:latest + container_name: jupyterhub-sftpgo + hostname: jupytersftp + command: sftpgo serve --loaddata-from /config/local_config.json --loaddata-clean + expose: + - "2022" + - "8080" + environment: + SFTPGO_DATA_PROVIDER__CREATE_DEFAULT_ADMIN: true + SFTPGO_DEFAULT_ADMIN_USERNAME: admin + SFTPGO_DEFAULT_ADMIN_PASSWORD: admin2025 + SFTPGO_HTTPD__BINDINGS__0__CLIENT_IP_PROXY_HEADER: X-Real-IP + volumes: + - jupyterhub-shared:/volumes/shared + - jupyterhub-course:/volumes/course + - jupyterhub-web:/volumes/web + - ./sftpgo_config.json:/config/local_config.json:ro + + networks: + - jupyterhub-network + restart: unless-stopped + networks: jupyterhub-network: name: jupyterhub-network @@ -32,6 +74,44 @@ networks: volumes: jupyterhub-data: + driver: local + driver_opts: + type: none + o: bind + device: ./jupyterhub_volumes/jupyterhub jupyterhub-shared: + driver: local + driver_opts: + type: none + o: bind + device: ./jupyterhub_volumes/shared jupyterhub-course: - \ No newline at end of file + driver: local + driver_opts: + type: none + o: bind + device: ./jupyterhub_volumes/course + jupyterhub-web: + driver: local + driver_opts: + type: none + o: bind + device: ./jupyterhub_volumes/web + jupyterhub-caddy-data: + driver: local + driver_opts: + type: none + o: bind + device: ./jupyterhub_volumes/caddy/data + jupyterhub-caddy-config: + driver: local + driver_opts: + type: none + o: bind + device: ./jupyterhub_volumes/caddy/config + jupyterhub-users: + driver: local + driver_opts: + type: none + o: bind + device: ./jupyterhub_volumes/users \ No newline at end of file diff --git a/install_packages.sh b/install_packages.sh old mode 100644 new mode 100755 diff --git a/jupyterhub_config.py b/jupyterhub_config.py index 2334e2e..652691f 100644 --- a/jupyterhub_config.py +++ b/jupyterhub_config.py @@ -1,6 +1,6 @@ import os -# Base configuration +# Base configuration coucou c.JupyterHub.spawner_class = 'dockerspawner.DockerSpawner' # Enable debug logs @@ -88,79 +88,8 @@ c.Authenticator.allow_all = True c.Authenticator.admin_users = {'admin'} # Listening port -c.JupyterHub.bind_url = 'http://0.0.0.0:8000' +c.JupyterHub.bind_url = 'http://0.0.0.0:8000/jupyter/' # Timeout c.Spawner.start_timeout = 300 c.Spawner.http_timeout = 120 -import os - -# Configuration de base -c.JupyterHub.spawner_class = 'dockerspawner.DockerSpawner' - -# Activer les logs de debug -c.JupyterHub.log_level = 'DEBUG' -c.Spawner.debug = True - -# Image Docker à utiliser pour les containers étudiants -c.DockerSpawner.image = 'jupyterhub-student:latest' - -# Réseau Docker (créez-le avec: docker network create jupyterhub-network) -c.DockerSpawner.network_name = 'jupyterhub-network' - -# Connexion au socket Docker d'OrbStack depuis le container hub -c.DockerSpawner.client_kwargs = {'base_url': 'unix:///var/run/docker.sock'} - -# IMPORTANT : URL interne pour communiquer entre containers -# Le hub container communique avec les user containers via le réseau Docker -c.JupyterHub.hub_ip = '0.0.0.0' -c.JupyterHub.hub_connect_ip = 'jupyterhub' - -# Configuration réseau pour les containers étudiants -c.DockerSpawner.use_internal_ip = True -c.DockerSpawner.network_name = 'jupyterhub-network' -c.DockerSpawner.extra_host_config = {'network_mode': 'jupyterhub-network'} - -# Supprimer les containers après déconnexion (optionnel, mettre False pour garder les containers) -c.DockerSpawner.remove = True - -# Nommage des containers -c.DockerSpawner.name_template = "jupyter-{username}" - -# Montage de volumes pour persister les données des étudiants -# Définir la racine à /home/jovyan pour voir tous les dossiers -notebook_dir = '/home/jovyan/work' -c.DockerSpawner.notebook_dir = notebook_dir - -# Volume personnel pour chaque étudiant + volume partagé -c.DockerSpawner.volumes = { - # Volume personnel (persistant) - monté dans work/ - 'jupyterhub-user-{username}': '/home/jovyan/work', - # Volume partagé entre tous les étudiants - 'jupyterhub-shared': '/home/jovyan/work/shared', - # Volume partagé en lecture seule pour les fichiers du cours (optionnel) - 'jupyterhub-course': { - 'bind': '/home/jovyan/work/course', - 'mode': 'ro' # read-only - } -} - -# Configuration de la mémoire et CPU (ajustez selon vos besoins) -c.DockerSpawner.mem_limit = '2G' -c.DockerSpawner.cpu_limit = 1.0 - -# Pour créer une liste d'utilisateurs autorisés, décommentez et modifiez: -# c.Authenticator.allowed_users = {'etudiant1', 'etudiant2', 'etudiant3'} - -# Ou autoriser n'importe quel utilisateur avec le bon mot de passe: -c.Authenticator.allow_all = True - -# Configuration admin -c.Authenticator.admin_users = {'admin'} - -# Port d'écoute -c.JupyterHub.bind_url = 'http://0.0.0.0:8000' - -# Timeout -c.Spawner.start_timeout = 300 -c.Spawner.http_timeout = 120 \ No newline at end of file diff --git a/jupyterhub_volumes/web/index.html b/jupyterhub_volumes/web/index.html new file mode 100644 index 0000000..50e94b1 --- /dev/null +++ b/jupyterhub_volumes/web/index.html @@ -0,0 +1,13 @@ + + +
+