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 -dCollegati ai container appena avviati, crea un utente e installa il notebook pacchetto:
docker exec -it jupyterhub /bin/bash
adduser 
pip install notebookOra 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 filesDocker 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-dummyauthenticatorDobbiamo 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 = TruePer 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 upNon 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!