Índice del diarioDockup / nota de campo
Note / self-host-jupyterlab

Cómo alojar JupyterLab por tu cuenta en 2026: tokens, kernels y notebooks persistentes

Implementa JupyterLab con el puerto adecuado, almacenamiento duradero, TLS, autenticación y copias de seguridad. Soluciona los problemas que aparecen cuando el proxy descarta los WebSockets de los kernels en producción.

La demostración más sencilla de JupyterLab solo demuestra que un proceso escucha en el puerto 8888. En producción se necesitan pruebas más sólidas. Debe superar este escenario incluso después de reemplazar el contenedor: iniciar sesión con un token, iniciar un kernel, ejecutar una celda de notebook, guardar el resultado, volver a conectar el WebSocket y reabrir el notebook.

JupyterLab se implementa con un objetivo claro: disponer de notebooks en el navegador junto a los datos y la capacidad de cómputo. El problema más habitual de su implementación es que el proxy descarte los WebSockets de los kernels o que los notebooks montados pertenezcan a root, por lo que la gestión de la URL pública y el estado persistente requieren la misma atención que el arranque de la imagen.

Demuestra que JupyterLab sobrevive a un reemplazo

Haz un inventario de todos los artefactos persistentes: notebooks, datos, entornos y archivos de dependencias reproducibles. Monta /home/jovyan/work antes del bootstrap, escribe datos de ejemplo inocuos y reemplaza el contenedor para demostrar que esa ruta es realmente persistente. Incluye también la configuración que modifica la interpretación de los datos almacenados, no solo el directorio más grande.

Define la retención, copia las copias de seguridad fuera del host y ejecuta una restauración en un entorno limpio. La prueba de JupyterLab se completa cuando se recuperan los notebooks, los datos y las especificaciones del entorno, y una celda representativa produce el resultado esperado. Si las snapshots forman parte del plan, usa la guía sobre PITR frente a snapshots para documentar qué puede recuperar cada mecanismo.

Define primero el éxito de JupyterLab

No dejes que la imagen de JupyterLab determine accidentalmente la arquitectura de producción. La imagen proporciona un proceso en el puerto 8888; el almacenamiento, el routing y los requisitos externos siguen necesitando ciclos de vida definidos deliberadamente. El requisito del runtime local son montajes de datos explícitos y una capacidad de cómputo dimensionada para cargas de trabajo de notebooks. Mantén explícito su ciclo de vida para que mover JupyterLab entre hosts no cambie su comportamiento de forma silenciosa.

La implementación está lista para pruebas más exhaustivas cuando puede iniciar sesión con un token, iniciar un kernel, ejecutar una celda de notebook, guardar el resultado, volver a conectar el WebSocket y reabrir el notebook. Sigue la transacción en los logs y supervisa la RAM y la CPU de los kernels, las copias de datos, el entrenamiento de modelos y los procesos de language server, en lugar de la interfaz web de JupyterLab. Estas observaciones revelan si la topología actual aísla el componente adecuado.

Cinco comprobaciones más sólidas que la salud del contenedor

El registro de la release de JupyterLab necesita datos concretos, no un «parece correcto». Guarda el digest de la imagen seleccionada, la suma de comprobación de la configuración, el hostname público y el resultado con marca de tiempo de estas acciones: iniciar sesión con un token, iniciar un kernel, ejecutar una celda de notebook, guardar el resultado, volver a conectar el WebSocket y reabrir el notebook. Usa datos de ejemplo que no sean de producción para que la comprobación pueda ejecutarse después de cada implementación.

Demuestra por separado dos eventos del ciclo de vida. Un reemplazo del contenedor debe conservar el funcionamiento normal; una recuperación limpia debe demostrar que se recuperan los notebooks, los datos y las especificaciones del entorno, y que una celda representativa produce el resultado esperado. Mientras se ejecutan las comprobaciones, mide la RAM y la CPU de los kernels, las copias de datos, el entrenamiento de modelos y los procesos de language server, en lugar de la interfaz web de JupyterLab, y conserva el resultado como el rango esperado para esta versión.

Prueba también una condición denegada o no válida: envía una entrada inocua cerca del límite de recursos o de formato asociado a este límite: el proxy descarta los WebSockets de los kernels o los notebooks montados pertenecen a root. JupyterLab debe fallar de forma diagnosticable y no debe sobrescribir un estado saludable. Restablece la condición válida, vuelve a ejecutar el ejemplo y adjunta los logs relevantes con la información sensible redactada. Estos artefactos aportan pruebas concretas para tomar una futura decisión de rollback.

Inicia JupyterLab con valores predeterminados observables

El primer contenedor debe ser fácil de eliminar y recrear. Mantén los datos fuera de la capa escribible, enlaza el puerto 8888 solo donde pueda alcanzarlo el proxy y pasa la configuración en tiempo de ejecución.

docker run -d \
  --name jupyterlab \
  --restart unless-stopped \
  -p 127.0.0.1:8888:8888 \
  -v jupyterlab-data:/home/jovyan/work \
  -e JUPYTER_TOKEN=replace-with-a-long-random-value \
  quay.io/jupyter/minimal-notebook:latest

Fija la versión de la imagen después de la prueba inicial. Lee el primer error del arranque en lugar del mensaje final de reinicio, verifica cada montaje con docker inspect y sigue los logs mientras inicias sesión con un token, inicias un kernel, ejecutas una celda de notebook, guardas el resultado, vuelves a conectar el WebSocket y reabres el notebook. Esta secuencia permite distinguir un comando incorrecto de la imagen de un problema de dependencias o permisos.

No concedas a JupyterLab acceso a todo el host

Cierra la ventana de bootstrap en cuanto exista el primer administrador de confianza. El problema concreto de JupyterLab es desactivar el token en un notebook expuesto a Internet o montar rutas amplias del host; el límite más seguro consiste en mantener activada la autenticación mediante token, montar solo los datos previstos y no exponer un terminal privilegiado del host de forma despreocupada.

Trata JUPYTER_TOKEN según su función en JupyterLab: mantén los valores sensibles fuera de Git, documenta los efectos de la rotación y nunca sustituyas un ejemplo público en producción. La red privada debe transportar las credenciales de las dependencias, y los roles dentro de JupyterLab deben conceder la acción útil mínima. Mantén fuera de los logs habituales los cuerpos de las solicitudes sensibles y las respuestas de los proveedores.

Prueba JupyterLab desde fuera del servidor

Elige el hostname definitivo de JupyterLab antes de que los usuarios guarden callbacks o ajustes del cliente; después, dirige el notebook server mediante HTTPS con soporte para WebSockets. La ruta de la plataforma debe terminar TLS una sola vez y apuntar al puerto privado 8888.

Ejecuta externamente la transacción de aceptación. Si el cliente nunca llega a JupyterLab, usa la lista de comprobación de validación de SSL para verificar el DNS y el certificado. Si la solicitud llega a JupyterLab, pero el proxy descarta los WebSockets de los kernels o los notebooks montados pertenecen a root, deja de cambiar las redirecciones del proxy e inspecciona el límite específico de la aplicación.

Logs que responden a la siguiente pregunta

Usa iniciar sesión con un token, iniciar un kernel, ejecutar una celda de notebook, guardar el resultado, volver a conectar el WebSocket y reabrir el notebook como prueba de humo de JupyterLab después de cada implementación. Sus métricas complementarias son la RAM y la CPU de los kernels, las copias de datos, el entrenamiento de modelos y los procesos de language server, en lugar de la interfaz web de JupyterLab; configura alertas cuando esos recursos se acerquen a un punto que degrade la acción del usuario.

El principal riesgo de cambio es que los paquetes de la imagen base, las extensiones de notebooks y los archivos de entorno necesitan una prueba de reproducibilidad antes de las actualizaciones. Una release segura parte de una snapshot restaurable y valida cualquier cambio de estado unidireccional antes de mover el tráfico. Cuando el proxy descarta los WebSockets de los kernels o los notebooks montados pertenecen a root, conserva el contenedor fallido el tiempo suficiente para leer su configuración y el primer error.

Una implementación en Dockup también necesita una prueba de aceptación de JupyterLab

La capa de plataforma para JupyterLab consta del puerto 8888, el ingress, TLS, la configuración del runtime, el almacenamiento y la conectividad con las dependencias. Dockup puede reproducir estos elementos para su propia infraestructura o para un servidor al que se conecte el cliente.

Después, el operador completa la capa de producto: dirige el notebook server mediante HTTPS con soporte para WebSockets; aplica esta regla de acceso —mantener activada la autenticación mediante token, montar solo los datos previstos y no exponer un terminal privilegiado del host de forma despreocupada—; y ejecuta «iniciar sesión con un token, iniciar un kernel, ejecutar una celda de notebook, guardar el resultado, volver a conectar el WebSocket y reabrir el notebook». Registrar esta prueba junto con la implementación evita confundir el aprovisionamiento automatizado con la disponibilidad de la aplicación.

Preguntas frecuentes

¿Qué necesita JupyterLab para una implementación en producción?

Dirige el contenedor de JupyterLab en el puerto 8888 a través de un único origen HTTPS. El requisito del runtime local son montajes de datos explícitos y una capacidad de cómputo dimensionada para cargas de trabajo de notebooks. No consideres listo JupyterLab hasta que puedas iniciar sesión con un token, iniciar un kernel, ejecutar una celda de notebook, guardar el resultado, volver a conectar el WebSocket y reabrir el notebook.

¿Qué datos de JupyterLab deben incluirse en una copia de seguridad?

Haz persistir /home/jovyan/work e incluye notebooks, datos, entornos y archivos de dependencias reproducibles en el mismo manifiesto de recuperación. Una restauración limpia de JupyterLab solo se completa cuando se recuperan los notebooks, los datos y las especificaciones del entorno, y una celda representativa produce el resultado esperado.

¿JupyterLab necesita HTTPS detrás de un reverse proxy?

Usa HTTPS para el origen público de JupyterLab y mantén el puerto 8888 en la ruta interna. Aplica correctamente el ajuste de JupyterLab: dirige el notebook server mediante HTTPS con soporte para WebSockets. En JupyterLab, HTTPS protege las credenciales o el contenido del usuario durante el tránsito y mantiene coherente el comportamiento del cliente sensible al origen.

¿Cómo se debe probar una actualización de JupyterLab?

Restaura el estado actual de JupyterLab en una implementación aislada, aplica la versión candidata y repite su transacción de aceptación. Presta especial atención porque los paquetes de la imagen base, las extensiones de notebooks y los archivos de entorno necesitan una prueba de reproducibilidad antes de las actualizaciones. Conserva la imagen anterior de JupyterLab hasta comprender sus límites de migración de datos y rollback.