Questo articolo descrive come configurare Jupyter dietro il proxy inverso Nginx, poiché tale configurazione non è molto ovvia per molte persone. Ci sono molti problemi e concetti su GitHub ed è difficile scegliere la soluzione giusta per questo problema. Inoltre, potresti trovare molti articoli diversi che descrivono come farlo, ma la maggior parte di essi sono obsoleti e non trattano bene la configurazione CORS.
Poiché l'argomento è ancora di tendenza, ho deciso di rinnovare l'articolo e semplificare la configurazione.
Grazie per i tuoi commenti di seguito, Andrew Barker . Scopri la versione aggiornata dell'articolo.
Configurazione Docker
In questa sezione dell'articolo, tratteremo il caso in cui potrebbe essere necessario avviare Jupyter o JupyterHub in un normale ambiente Docker.
Configurazione di JupyterHub
Per prima cosa, creiamo una cartella in cui inseriremo tutti i nostri file di configurazione.
Ecco la nostra struttura finale:
mkdir docker
tree docker
docker
├── docker-compose.yaml
├── jupyter_notebook_config.py
└── nginx.conf
Composizione Docker
Per semplificare tutto, ho creato docker-compose.yaml
, che descrive i nostri servizi:
version: "3.7"
services:
nginx:
image: nginx:alpine
volumes:
- "./nginx.conf:/etc/nginx/nginx.conf:ro"
ports:
- 8080:8080
links:
- "jupyterhub"
jupyterhub:
image: jupyterhub/jupyterhub
container_name: jupyterhub
volumes:
- "./jupyter_notebook_config.py:/root/.jupyter/jupyter_notebook_config.py:ro"
La configurazione è semplice:un semplice piccolo container Nginx Docker davanti a Jupyterhub.
Entrambi sono stati lanciati dalle loro ultime versioni.
Configurazione Nginx
Nginx è sulla porta 8080 e in ascolto sulla porta 8080 anche.
MOLTO IMPORTANTE: nginx.conf
contiene la configurazione del proxy inverso.
Se il tuo Nginx si trova su una porta diversa da 80 o 443 , è necessario utilizzare la seguente direttiva di configurazione:
proxy_set_header Host $host:$server_port;
Per Nginx, che si trova sulle porte predefinite, usa default
configurazione:
proxy_set_header Host $host;
Se commetti un errore qui, inizierai a ricevere Blocking Cross Origin API request for /api/contents
messaggi di errore.
Anche in questo caso, il motivo principale di questi messaggi non sono le porte uguali per il collegamento del servizio e l'esportazione per i contenitori Nginx.
Ecco il mio nginx.conf
per l'ascolto sulla porta 8080
:
worker_processes 1;
events { worker_connections 1024; }
http {
sendfile on;
upstream ml {
server jupyterhub:8000;
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 8080;
location / {
proxy_pass http://ml;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# websocket headers
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
}
Configurazione di Jupyter
Per la configurazione di JupyterHub, utilizzeremo la seguente configurazione posizionata in /root/.jupyter/jupyter_notebook_config.py
:
# get the config object
c = get_config()
# JupyterHub listen address
c.JupyterHub.hub_ip = '0.0.0.0'
# JupyterHub connect hostname.
# In our case it's 'jupyterhub' by the name of the service from docker-compose.yaml
c.JupyterHub.hub_connect_ip = 'jupyterhub'
# Location for users notebooks
c.Spawner.notebook_dir = '~/'
Lancio di Jupyrter dietro Nginx Proxy
Non ho avuto molto tempo per creare un nuovo contenitore e/o giocare con le impostazioni di autenticazione dell'utente. Lo scopo principale è fornire una soluzione per Bloccare le richieste API cross-Origin per /api/contents problemi.
Quindi, ecco come avviare questa configurazione:
docker-compose up -d
Collegati ai container appena avviati, crea un utente e installa il notebook pacchetto:
docker exec -it jupyterhub /bin/bash
adduser
pip install notebook
Ora puoi connetterti a JupterHub e utilizzare il nome utente e la password creati come credenziali di accesso.
Configurazione Docker Swarm
In questa sezione dell'articolo tratteremo il caso in cui potrebbe essere necessario avviare Jupyter o JupyterHub in modalità Docker Swarm.
Modifichiamo leggermente la nostra cartella del progetto:
.
├── .env
├── docker-compose.yaml
├── jupyterhub
│ ├── Dockerfile
│ ├── jupyterhub_config.py
└── nginx
└── nginx.conf
3 directories, 5 files
Docker Compose (Swarm)
Ecco come funziona il nostro docker-compose.yaml
il file sarà simile a:
version: "3.7"
services:
# Configuration for reverse proxy
nginx:
image: nginx:alpine
volumes:
- "./nginx/nginx.conf:/etc/nginx/nginx.conf:ro"
ports:
- 8080:8080
networks:
default:
jupyterhub_network:
aliases:
- nginx
# Configuration for Hub+Proxy
jupyterhub:
env_file: .env
build: jupyterhub
image: jupyterhub_customized
hostname: jupyterhub
volumes:
- "./jupyterhub/jupyterhub_config.py:/srv/jupyterhub/jupyterhub_config.py:ro"
- "/var/run/docker.sock:/var/run/docker.sock"
ports:
- 8000:8000
networks:
default:
jupyterhub_network:
aliases:
- jupyterhub
environment:
# Name of the Docker image for the single-user servers
DOCKER_JUPYTER_IMAGE: ${DOCKER_JUPYTER_IMAGE}
# The name of the Docker network used by the services
DOCKER_NETWORK_NAME: ${COMPOSE_PROJECT_NAME}_jupyterhub_network
# The IP address of the Hub service within the docker network
deploy:
replicas: 1
placement:
constraints:
- node.role == manager
# Configuration for the single-user servers
jupyterlab:
image: ${DOCKER_JUPYTER_IMAGE}
command: echo
networks:
jupyterhub_network:
driver: overlay
volumes:
jupyterhub_data:
Le variabili di ambiente Docker-Compose sono definite in .env
file:
# Name of our Docker Compose project
COMPOSE_PROJECT_NAME="jupyterhub"
DOCKER_JUPYTER_IMAGE="jupyterhub/singleuser:2.2"
Configurazione JupyterHub (swarm)
Dobbiamo creare la nostra immagine personalizzata di JupyterHub per includere automaticamente dockerspawner, dummyauthenticator e qualsiasi altro modulo di cui potresti aver bisogno (ad esempio, per supportare diversi metodi di autenticazione).
# Do not forget to pin down the version
FROM jupyterhub/jupyterhub
# Install dependencies (for advanced authentication and spawning)
RUN pip install \
dockerspawner \
jupyterhub-dummyauthenticator
Dobbiamo anche fornire la configurazione corretta per JupyterHub:
import os
NETWORK_NAME = os.environ['DOCKER_NETWORK_NAME']
DOCKER_JUPYTER_IMAGE = os.environ['DOCKER_JUPYTER_IMAGE']
# get the config object
c = get_config()
c.ConfigurableHTTPProxy.should_start = True
c.JupyterHub.authenticator_class = 'dummyauthenticator.DummyAuthenticator'
c.JupyterHub.hub_ip = '0.0.0.0'
c.JupyterHub.hub_connect_ip = 'jupyterhub'
c.JupyterHub.spawner_class = 'dockerspawner.SwarmSpawner'
c.JupyterHub.tornado_settings = {'slow_spawn_timeout': 30}
c.SwarmSpawner.image = DOCKER_JUPYTER_IMAGE
c.SwarmSpawner.network_name = NETWORK_NAME
c.SwarmSpawner.remove_containers = True
c.Spawner.cmd = ["jupyter", "labhub"]
c.Spawner.args = ['--allow-root']
c.Spawner.notebook_dir = '~/'
c.Spawner.debug = True
c.SwarmSpawner.debug = True
c.SwarmSpawner.host_ip = '0.0.0.0'
c.SwarmSpawner.http_timeout = 300
c.SwarmSpawner.start_timeout = 300
#c.JupyterHub.log_level = 00
#c.ConfigurableHTTPProxy.debug = True
Per ulteriori informazioni, ti consiglio vivamente di controllare i seguenti link:
- Utilizzo di SwarmSpawner (esempio ufficiale)
- Documentazione ufficiale di SwarmSpawner (JupyterHub)
- Distribuzione di un server JupyterHub containerizzato con Docker (articolo)
- Come eseguire JupyterHub nell'ambiente Docker swarm usando swarmSpawner (articolo)
Configurazione Nginx (swarm)
La configurazione di Nginx rimarrà invariata, ma mettiamola qui per completezza dell'esempio:
worker_processes 1;
events { worker_connections 1024; }
http {
sendfile on;
upstream ml {
server jupyterhub:8000;
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 8080;
location / {
proxy_pass http://ml;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# websocket headers
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
}
Esempio dimostrativo
Per avviare la demo fornita, esegui il seguente comando:
docker-compose build
docker-compose up
Non appena il servizio si avvia, connettiti all'indirizzo IP esterno del tuo server alla porta 8080:
Dovresti vedere il seguente output della console:
Nel browser dovresti vedere la seguente pagina:
Utilizzare qualsiasi nome utente e non fornire alcuna password. Fai clic su Accedi e verrai reindirizzato all'ambiente del laboratorio utente:
Riepilogo
Spero che questa piccola nota ti aiuti a risparmiare un po' di tempo. Se l'hai trovato utile, aiutaci a diffonderlo nel mondo!
Resta sintonizzato!