Compare commits
2 Commits
ae77f71b6c
...
57bf9934a3
| Author | SHA1 | Date | |
|---|---|---|---|
| 57bf9934a3 | |||
|
|
a3608759c5 |
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
/jupyterhub_volumes/users
|
||||
/jupyterhub_volumes/shared
|
||||
/jupyterhub_volumes/jupyterhub
|
||||
/jupyterhub_volumes/caddy
|
||||
43
Caddyfile
Normal file
43
Caddyfile
Normal file
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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:
|
||||
|
||||
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
|
||||
0
install_packages.sh
Normal file → Executable file
0
install_packages.sh
Normal file → Executable file
@@ -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
|
||||
13
jupyterhub_volumes/web/index.html
Normal file
13
jupyterhub_volumes/web/index.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Course Portal</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Welcome</h1>
|
||||
<ul>
|
||||
<li><a href="/jupyter/">JupyterHub</a></li>
|
||||
<li><a href="/static/">Static Site</a></li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
45
sftpgo_config.json
Normal file
45
sftpgo_config.json
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"name": "shared_data",
|
||||
"mapped_path": "/volumes/shared",
|
||||
"description": "Dossier partagé entre utilisateurs",
|
||||
"filesystem": {
|
||||
"provider": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "web_site",
|
||||
"mapped_path": "/volumes/web",
|
||||
"description": "Site web static",
|
||||
"filesystem": {
|
||||
"provider": 0
|
||||
}
|
||||
}
|
||||
],
|
||||
"users": [
|
||||
{
|
||||
"username": "admin",
|
||||
"password": "admin2025",
|
||||
"status": 1,
|
||||
"home_dir": "/volumes/course",
|
||||
"permissions": {
|
||||
"/": ["*"]
|
||||
},
|
||||
"virtual_folders": [
|
||||
{
|
||||
"name": "shared_data",
|
||||
"virtual_path": "/shared",
|
||||
"quota_size": -1,
|
||||
"quota_files": -1
|
||||
},
|
||||
{
|
||||
"name": "web_site",
|
||||
"virtual_path": "/web",
|
||||
"quota_size": -1,
|
||||
"quota_files": -1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -39,16 +39,10 @@ echo ""
|
||||
echo -e "${BLUE}🔨 Building JupyterHub image...${NC}"
|
||||
docker build -t jupyterhub-hub:latest -f Dockerfile.hub .
|
||||
|
||||
# Create volumes if they don't exist
|
||||
echo ""
|
||||
echo -e "${BLUE}💾 Creating shared volumes...${NC}"
|
||||
docker volume create jupyterhub-shared 2>/dev/null || echo " Volume jupyterhub-shared already exists"
|
||||
docker volume create jupyterhub-course 2>/dev/null || echo " Volume jupyterhub-course already exists"
|
||||
|
||||
# Start the stack
|
||||
echo ""
|
||||
echo -e "${BLUE}🚀 Starting JupyterHub...${NC}"
|
||||
docker-compose up -d
|
||||
docker-compose up -d --remove-orphans
|
||||
|
||||
# Wait for service to be ready
|
||||
echo ""
|
||||
|
||||
Reference in New Issue
Block a user