Dieser Artikel beschreibt, wie Jupyter hinter dem Nginx-Reverse-Proxy konfiguriert wird, da eine solche Konfiguration für viele Menschen nicht sehr offensichtlich ist. Es gibt viele Probleme und Kernpunkte auf GitHub, und es ist schwierig, die richtige Lösung für dieses Problem zu finden. Außerdem finden Sie möglicherweise viele verschiedene Artikel, in denen beschrieben wird, wie dies zu tun ist, aber die meisten davon sind veraltet und behandeln die CORS-Konfiguration nicht gut.
Da das Thema immer noch im Trend liegt, habe ich mich entschlossen, den Artikel zu erneuern und die Konfiguration zu vereinfachen.
Vielen Dank für Ihre Kommentare unten, Andrew Barker . Holen Sie sich die aktualisierte Version des Artikels.
Docker-Konfiguration
In diesem Abschnitt des Artikels behandeln wir den Fall, in dem Sie möglicherweise Jupyter oder JupyterHub in einer normalen Docker-Umgebung starten müssen.
JupyterHub-Konfiguration
Lassen Sie uns zuerst einen Ordner erstellen, in dem wir alle unsere Konfigurationsdateien ablegen.
Hier ist unsere endgültige Struktur:
mkdir docker
tree docker
docker
├── docker-compose.yaml
├── jupyter_notebook_config.py
└── nginx.conf
Docker Compose
Um alles zu vereinfachen, habe ich docker-compose.yaml
erstellt , die unsere Dienstleistungen beschreibt:
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"
Die Konfiguration ist unkompliziert – ein einfacher kleiner Nginx-Docker-Container vor Jupyterhub.
Beide wurden von ihren neuesten Versionen gestartet.
Nginx-Konfiguration
Nginx sitzt auf Port 8080 und auf Port 8080 lauschen auch.
SEHR WICHTIG: nginx.conf
enthält die Reverse-Proxy-Konfiguration.
Wenn Ihr Nginx auf einem anderen Port als 80 sitzt oder 443 , müssen Sie die folgende Konfigurationsdirektive verwenden:
proxy_set_header Host $host:$server_port;
Verwenden Sie für Nginx, das sich auf Standardports befindet, default
Konfiguration:
proxy_set_header Host $host;
Wenn Sie hier einen Fehler machen, erhalten Sie Blocking Cross Origin API request for /api/contents
Fehlermeldungen.
Auch hier ist der Hauptgrund für diese Meldungen nicht die gleichen Ports für die Dienstbindung und den Export für Nginx-Container.
Hier ist meine nginx.conf
zum Abhören von Port 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;
}
}
}
Jupyter-Konfiguration
Für die JupyterHub-Konfiguration verwenden wir die folgende Konfiguration 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 = '~/'
Jupyrter hinter Nginx Proxy starten
Ich hatte nicht viel Zeit, um einen neuen Container zu erstellen und/oder mit den Benutzerauthentifizierungseinstellungen zu spielen. Der Hauptzweck besteht darin, eine Lösung zum Blockieren von Cross-Origin-API-Anfragen für /api/contents bereitzustellen Probleme.
So können Sie diese Konfiguration starten:
docker-compose up -d
Stellen Sie eine Verbindung zu gerade gestarteten Containern her, erstellen Sie einen Benutzer und installieren Sie das Notebook Paket:
docker exec -it jupyterhub /bin/bash
adduser
pip install notebook
Jetzt können Sie sich mit JupterHub verbinden und Ihren erstellten Benutzernamen und Ihr Passwort als Anmeldeinformationen verwenden.
Docker Swarm-Konfiguration
In diesem Abschnitt des Artikels behandeln wir den Fall, dass Sie Jupyter oder JupyterHub möglicherweise in einem Docker Swarm-Modus starten müssen.
Lassen Sie uns unseren Projektordner leicht ändern:
.
├── .env
├── docker-compose.yaml
├── jupyterhub
│ ├── Dockerfile
│ ├── jupyterhub_config.py
└── nginx
└── nginx.conf
3 directories, 5 files
Docker Compose (Schwarm)
So funktioniert unsere docker-compose.yaml
Datei sieht so aus:
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:
Docker-Compose-Umgebungsvariablen werden unter .env
definiert Datei:
# Name of our Docker Compose project
COMPOSE_PROJECT_NAME="jupyterhub"
DOCKER_JUPYTER_IMAGE="jupyterhub/singleuser:2.2"
JupyterHub-Konfiguration (Schwarm)
Wir müssen unser eigenes benutzerdefiniertes Image von JupyterHub erstellen, um Dockerspawner, DummyAuthenticator und alle anderen Module, die Sie möglicherweise benötigen, automatisch einzuschließen (z. B. um verschiedene Authentifizierungsmethoden zu unterstützen).
# Do not forget to pin down the version
FROM jupyterhub/jupyterhub
# Install dependencies (for advanced authentication and spawning)
RUN pip install \
dockerspawner \
jupyterhub-dummyauthenticator
Wir müssen auch die richtige Konfiguration für JupyterHub bereitstellen:
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
Für weitere Informationen empfehle ich Ihnen dringend, sich die folgenden Links anzusehen:
- Mit SwarmSpawner (offizielles Beispiel)
- Offizielle SwarmSpawner-Dokumentation (JupyterHub)
- Bereitstellen eines Container-JupyterHub-Servers mit Docker (Artikel)
- So führen Sie JupyterHub in einer Docker-Schwarmumgebung mit swarmSpawner aus (Artikel)
Nginx-Konfiguration (Schwarm)
Die Nginx-Konfiguration bleibt unverändert, aber der Vollständigkeit halber fügen wir sie hier ein:
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;
}
}
}
Demo-Beispiel
Um die bereitgestellte Demo zu starten, führen Sie den folgenden Befehl aus:
docker-compose build
docker-compose up
Sobald der Dienst startet, verbinden Sie sich mit der externen IP-Adresse Ihres Servers mit Port 8080:
Sie sollten die folgende Konsolenausgabe sehen:
Im Browser sollten Sie die folgende Seite sehen:
Verwenden Sie einen beliebigen Benutzernamen und geben Sie kein Passwort ein. Klicken Sie auf Anmelden Schaltfläche und Sie werden zur Benutzerlaborumgebung weitergeleitet:
Zusammenfassung
Ich hoffe, dieser kleine Hinweis hilft Ihnen, etwas Zeit zu sparen. Wenn Sie es nützlich fanden, helfen Sie bitte, es in der Welt zu verbreiten!
Bleiben Sie dran!