JupyterLab est parfait pour prototyper, analyser des données et partager du code. En revanche, l’ouvrir sur Internet “tel quel” (port exposé, pas de HTTPS, pas de persistance) est une très mauvaise idée : l’interface permet aussi d’exécuter du code.
Dans ce guide, on déploie JupyterLab proprement en production avec Docker Compose, un reverse proxy en HTTPS, une authentification solide et des volumes persistants.
Découvrir l’hébergement JupyterLab sur adgents.cloud
1) Le modèle de déploiement à choisir (solo vs équipe)
Avant de toucher à la configuration, clarifiez l’usage :
- Usage “1 personne” (vous ou un seul compte) : un JupyterLab unique derrière HTTPS + auth suffit.
- Usage “équipe / multi-comptes” : préférez un orchestrateur (souvent JupyterHub) pour gérer les sessions, les permissions et l’isolation. Si vous hébergez pour plusieurs clients, c’est quasiment indispensable.
Dans la suite, on reste volontairement sur un déploiement simple (un JupyterLab). Le principe reste le même si vous passez ensuite à JupyterHub : reverse proxy + HTTPS + WebSocket + sécurité.
2) Architecture recommandée en production
L’architecture “propre” ressemble à ceci :
- Reverse proxy (Caddy ou Nginx) : termine TLS, force HTTPS, gère WebSocket.
- JupyterLab : ne doit pas être exposé directement au public ; idéalement accessible seulement depuis le proxy.
- Volumes persistants : fichiers de travail + données + exports.
- Sauvegardes : automatisées, avec tests de restauration réguliers.
Pour une approche proxy robuste (WebSocket, headers, TLS), les exemples de configuration reverse proxy de la documentation JupyterHub sont une bonne référence d’architecture.
3) Docker Compose : un socle fiable (sans magie)
Pour éviter tout effet “boîte noire”, une approche simple est de partir d’une image Python, d’installer JupyterLab, puis de piloter le tout avec Docker Compose.
Dockerfile
FROM python:3.11-slim
RUN pip install --no-cache-dir jupyterlab==4.*
# Évite de lancer en root
RUN useradd -m -u 1000 app
USER app
WORKDIR /home/app
EXPOSE 8888
CMD ["jupyter", "lab", "--ip=0.0.0.0", "--port=8888", "--no-browser"]
docker-compose.yml
services:
jupyterlab:
build: .
container_name: jupyterlab
restart: unless-stopped
environment:
- JUPYTER_TOKEN=${JUPYTER_TOKEN}
command: >
jupyter lab
--ip=0.0.0.0
--port=8888
--no-browser
--ServerApp.token=${JUPYTER_TOKEN}
--ServerApp.allow_remote_access=True
volumes:
- jupyterlab_work:/home/app/work
expose:
- "8888"
volumes:
jupyterlab_work:
Points importants :
exposerend le port visible pour le réseau Docker, sans le publier en direct sur Internet.- Le token est défini (pas aléatoire) et géré via variable d’environnement.
- La persistance se fait via un volume Docker.
4) HTTPS : reverse proxy (Caddy recommandé)
Option A — Caddy (simple et très solide)
Caddy obtient et renouvelle automatiquement des certificats Let’s Encrypt :
Caddyfile (exemple) :
jupyterlab.mondomaine.fr {
reverse_proxy jupyterlab:8888
}
À vérifier :
- le DNS pointe vers le serveur
- le port 80/443 est ouvert
- le proxy gère bien les WebSockets (Caddy le fait nativement)
Option B — Nginx (classique en infra)
Nginx fonctionne très bien aussi, mais il faut être rigoureux sur TLS + headers + WebSocket.
5) Authentification et durcissement (le minimum vital)
L’objectif : un navigateur non authentifié ne doit jamais arriver sur un environnement capable d’exécuter du code.
Bonnes pratiques simples :
- Conserver un token fort (ou un mot de passe) côté Jupyter.
- Ajouter une barrière d’authentification au niveau du proxy (Basic Auth, SSO, ou un portail).
- Limiter l’accès réseau : idéalement, JupyterLab n’écoute que sur le réseau interne Docker et n’est pas publié en direct.
- Mises à jour : image applicative + proxy + OS, avec une cadence régulière.
Si vous devez ouvrir à plusieurs personnes, réfléchissez tôt à JupyterHub et à des comptes séparés.
6) Persistance : fichiers, données… et environnements Python
La persistance ne se limite pas aux fichiers :
- Fichiers de travail & données : volume
/home/app/work(ou un chemin dédié). - Dépendances Python : si vous faites des
pip installà la main dans un container, vous allez le regretter. Deux options propres :- construire une image personnalisée avec vos packages (reproductible)
- ou gérer un environnement (conda/venv) dans un volume dédié (attention aux droits et à la compatibilité)
Astuce : quand on veut un environnement stable, une image personnalisée est souvent le meilleur compromis.
7) Sauvegardes : la partie qui sauve des semaines
Sauvegarder un volume n’est pas “optionnel”. En pratique :
- sauvegardes automatiques (quotidiennes au minimum)
- rétention adaptée (courte + longue)
- tests de restauration : si vous ne testez jamais, vous n’avez pas de sauvegarde
Sur adgents.cloud, vous pouvez activer des sauvegardes automatiques et ajuster la fréquence (jusqu’à 1 par heure selon le besoin), avec une rétention longue.
Pour un exemple concret côté plateforme (HTTPS, sauvegardes, exploitation), vous pouvez lire : Bati : déployer sur adgents.cloud (HTTPS, sauvegardes, perf).
8) Dimensionnement, coûts et stabilité
JupyterLab peut consommer beaucoup selon les usages (pandas, ML, gros CSV). Planifiez :
- CPU/RAM : dimensionnez selon les besoins (et gardez une marge).
- Disque : datasets + caches + outputs, ça grossit vite.
- Arrêt/redémarrage : pouvoir arrêter quand vous n’en avez pas besoin évite de payer inutilement du compute.
C’est exactement le type de cas où un hébergement orienté “app” est utile : vous démarrez vite, vous ajustez CPU/RAM à la demande et vous gardez le stockage persistant.
9) Vidéo (FR)
Pour une présentation en français autour de Jupyter et JupyterLab : 
Conclusion
Un JupyterLab en production “propre” repose sur quelques fondamentaux : HTTPS, authentification solide, pas d’exposition directe, volumes persistants et sauvegardes.
Si vous voulez le déployer sans y passer des heures (et garder la possibilité de scaler, d’ajuster les capacités et de gérer les sauvegardes), regardez l’offre dédiée : hébergement JupyterLab sur adgents.cloud.
