--- title: "Cómo instalar JupyterLab en Ubuntu 24.04 con Nginx y HTTPS" description: "Instala JupyterLab en Ubuntu 24.04 en un entorno virtual, protégelo con contraseña, ejecútalo con systemd y publícalo con Nginx y HTTPS de Let's Encrypt." category: "Infraestructura de IA y ML" language: es source: https://cubepath.com/es/docs/infraestructura-de-ia-y-ml/instalacion-de-servidor-jupyter-notebook updated: 2026-09-25 --- # Cómo instalar JupyterLab en Ubuntu 24.04 con Nginx y HTTPS JupyterLab es el entorno web de Jupyter para trabajar con notebooks, terminales y archivos desde el navegador, muy usado en ciencia de datos y machine learning. Ejecutarlo en un servidor remoto te permite aprovechar su CPU, su memoria o su GPU desde cualquier equipo. En este tutorial instalarás JupyterLab en Ubuntu 24.04 dentro de un entorno virtual, lo protegerás con contraseña, lo ejecutarás como servicio de systemd y lo publicarás con Nginx y un certificado de Let's Encrypt. ## Requisitos previos - Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath, con un usuario no root con privilegios `sudo`. En esta guía el usuario se llama `your_user`. - Un dominio o subdominio con un registro DNS A apuntando a la IP del servidor. Los ejemplos usan `jupyter.your_domain`. - UFW activo con el acceso SSH permitido. > Advertencia: JupyterLab permite ejecutar código y abrir una terminal con los permisos del usuario que lo ejecuta. Quien obtenga acceso a la interfaz tiene, en la práctica, una shell en tu servidor. Usa una contraseña robusta y no lo ejecutes nunca como root. ## Paso 1: Instalar JupyterLab en un entorno virtual Ubuntu 24.04 no permite instalar paquetes con `pip` en el Python del sistema (PEP 668), y además es buena práctica aislar Jupyter en su propio entorno. Instala las herramientas para crear entornos virtuales: ```bash sudo apt update sudo apt install python3-venv python3-pip ``` Crea el entorno en tu directorio personal e instala JupyterLab: ```bash python3 -m venv ~/jupyter/venv ~/jupyter/venv/bin/pip install --upgrade pip ~/jupyter/venv/bin/pip install jupyterlab ``` Comprueba la versión instalada: ```bash ~/jupyter/venv/bin/jupyter lab --version ``` ```output 4.4.9 ``` Crea también el directorio donde guardarás los notebooks: ```bash mkdir -p ~/notebooks ``` ## Paso 2: Configurar la contraseña y el servidor Por defecto Jupyter genera un token aleatorio en cada arranque. Para un servidor permanente es más práctico usar una contraseña. El siguiente comando la pide dos veces y guarda su hash en `~/.jupyter/jupyter_server_config.json`: ```bash ~/jupyter/venv/bin/jupyter server password ``` ```output Enter password: Verify password: [JupyterPasswordApp] Wrote hashed password to /home/your_user/.jupyter/jupyter_server_config.json ``` Genera el archivo de configuración del servidor: ```bash ~/jupyter/venv/bin/jupyter server --generate-config ``` El comando crea `~/.jupyter/jupyter_server_config.py` con todas las opciones comentadas. Ábrelo: ```bash nano ~/.jupyter/jupyter_server_config.py ``` Añade al final estas líneas, sustituyendo `your_user`: ```python c.ServerApp.ip = "127.0.0.1" c.ServerApp.port = 8888 c.ServerApp.open_browser = False c.ServerApp.root_dir = "/home/your_user/notebooks" c.ServerApp.trust_xheaders = True ``` Qué hace cada opción: - `ip = "127.0.0.1"`: Jupyter solo escucha en local. El acceso desde fuera llegará siempre a través de Nginx, con HTTPS. - `root_dir`: el directorio que se muestra en el explorador de archivos de JupyterLab. - `trust_xheaders`: hace que Jupyter use las cabeceras `X-Forwarded-*` de Nginx para conocer la IP real del cliente y el esquema `https`. Prueba el servidor en primer plano: ```bash ~/jupyter/venv/bin/jupyter lab ``` ```output [I 2026-09-25 11:20:04.311 ServerApp] Jupyter Server 2.17.0 is running at: [I 2026-09-25 11:20:04.311 ServerApp] http://127.0.0.1:8888/lab ``` Si ves esas líneas, detén el servidor con `Ctrl+C` y confirma con `y`. ## Paso 3: Ejecutar JupyterLab como servicio de systemd Un servicio de systemd arranca Jupyter con el sistema, lo reinicia si falla y centraliza sus logs en el journal. Crea la unidad: ```bash sudo nano /etc/systemd/system/jupyter.service ``` ```ini [Unit] Description=JupyterLab After=network.target [Service] Type=simple User=your_user Group=your_user WorkingDirectory=/home/your_user/notebooks ExecStart=/home/your_user/jupyter/venv/bin/jupyter lab Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target ``` Al definir `User=`, systemd establece `HOME=/home/your_user`, así que Jupyter lee la configuración de `~/.jupyter` sin más ajustes. Activa e inicia el servicio: ```bash sudo systemctl daemon-reload sudo systemctl enable --now jupyter systemctl status jupyter --no-pager ``` ```output ● jupyter.service - JupyterLab Loaded: loaded (/etc/systemd/system/jupyter.service; enabled; preset: enabled) Active: active (running) since Thu 2026-09-25 11:23:40 UTC; 4s ago ``` Comprueba que responde en local: ```bash curl -sI http://127.0.0.1:8888/lab | head -n 1 ``` ```output HTTP/1.1 302 Found ``` La redirección `302` hacia la página de login es la respuesta esperada. Para ver los logs, usa `sudo journalctl -u jupyter -f`. ## Paso 4: Configurar Nginx como proxy inverso Nginx recibirá las conexiones HTTPS y las reenviará a Jupyter. JupyterLab usa WebSockets para comunicarse con los kernels, así que el proxy debe reenviar las cabeceras `Upgrade` y `Connection`. Instala Nginx y abre los puertos HTTP y HTTPS en el firewall: ```bash sudo apt install nginx sudo ufw allow 'Nginx Full' ``` Crea el archivo del sitio: ```bash sudo nano /etc/nginx/sites-available/jupyter ``` ```nginx map $http_upgrade $connection_upgrade { default upgrade; '' close; } server { listen 80; listen [::]:80; server_name jupyter.your_domain; client_max_body_size 100M; location / { proxy_pass http://127.0.0.1:8888; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_read_timeout 1d; } } ``` El bloque `map` envía `Connection: upgrade` solo cuando el cliente pide un WebSocket. `proxy_read_timeout 1d` evita que Nginx corte las conexiones de kernels que están un rato sin tráfico, y `client_max_body_size` permite subir archivos de hasta 100 MB desde el navegador. Activa el sitio, comprueba la sintaxis y recarga Nginx: ```bash sudo ln -s /etc/nginx/sites-available/jupyter /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginx ``` ```output nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful ``` ## Paso 5: Activar HTTPS con Let's Encrypt Instala Certbot con su plugin de Nginx y solicita el certificado. Certbot añade la configuración TLS al bloque `server` y una redirección de HTTP a HTTPS: ```bash sudo apt install certbot python3-certbot-nginx sudo certbot --nginx -d jupyter.your_domain --redirect ``` ```output Successfully received certificate. Certificate is saved at: /etc/letsencrypt/live/jupyter.your_domain/fullchain.pem ... Successfully deployed certificate for jupyter.your_domain to /etc/nginx/sites-enabled/jupyter Congratulations! You have successfully enabled HTTPS on https://jupyter.your_domain ``` El paquete de Ubuntu instala un timer de systemd que renueva el certificado automáticamente. Comprueba que la renovación funcionará: ```bash sudo certbot renew --dry-run ``` Abre `https://jupyter.your_domain` en el navegador. Verás la pantalla de login de Jupyter; introduce la contraseña del paso 2. Crea un notebook con el kernel **Python 3** y ejecuta una celda como `import sys; sys.version` para comprobar que el kernel responde a través del proxy. ## Paso 6: Añadir kernels de otros entornos virtuales El kernel por defecto usa el entorno virtual de Jupyter. Para trabajar con proyectos que tienen sus propias dependencias, crea un entorno por proyecto y regístralo como kernel, sin instalar Jupyter en él. Solo necesita `ipykernel`: ```bash python3 -m venv ~/venvs/analisis ~/venvs/analisis/bin/pip install ipykernel pandas matplotlib ~/venvs/analisis/bin/python -m ipykernel install --user --name analisis --display-name "Python (analisis)" ``` Lista los kernels disponibles: ```bash ~/jupyter/venv/bin/jupyter kernelspec list ``` ```output Available kernels: analisis /home/your_user/.local/share/jupyter/kernels/analisis python3 /home/your_user/jupyter/venv/share/jupyter/kernels/python3 ``` Recarga JupyterLab en el navegador y el nuevo kernel aparecerá en el lanzador. Para eliminar un kernel que ya no usas, ejecuta `~/jupyter/venv/bin/jupyter kernelspec remove analisis`. Para instalar paquetes desde un notebook, usa `%pip install nombre_paquete` en una celda: instala en el entorno del kernel activo, no en el de Jupyter. ## Alternativa: acceso solo por túnel SSH Si eres el único usuario y no quieres exponer Jupyter en internet, puedes saltarte los pasos 4 y 5. Como Jupyter escucha en `127.0.0.1`, crea un túnel SSH desde tu equipo local: ```bash ssh -N -L 8888:127.0.0.1:8888 your_user@your_server_ip ``` Mientras el comando esté en ejecución, abre `http://localhost:8888` en tu navegador local. El tráfico viaja cifrado dentro de la conexión SSH. ## Solución de problemas **El servicio no arranca.** Revisa `sudo journalctl -u jupyter -n 50 --no-pager`. Los errores habituales son una ruta incorrecta en `ExecStart`, un `User=` que no coincide con el propietario de `~/jupyter`, o que `root_dir` apunta a un directorio que no existe. **`502 Bad Gateway` en el navegador.** Nginx no puede conectar con Jupyter. Comprueba que el servicio está activo y que `curl -I http://127.0.0.1:8888/lab` responde en el servidor. **La página carga pero el kernel se queda en "Connecting" o "Disconnected".** Los WebSockets no pasan por el proxy. Verifica que la configuración de Nginx incluye `proxy_http_version 1.1` y las cabeceras `Upgrade` y `Connection`, y revisa `/var/log/nginx/error.log`. **`Blocking Cross Origin API request` o errores 403 al abrir notebooks.** La cabecera `Host` no llega a Jupyter. Asegúrate de que el bloque `location` contiene `proxy_set_header Host $host;`. **Olvidaste la contraseña.** Ejecuta de nuevo `~/jupyter/venv/bin/jupyter server password` y reinicia el servicio con `sudo systemctl restart jupyter`. ## Conclusión JupyterLab está funcionando como servicio en tu servidor Ubuntu 24.04, protegido con contraseña, accesible por HTTPS a través de Nginx y con kernels separados por proyecto. Como siguientes pasos, puedes instalar los drivers de NVIDIA y PyTorch en un kernel dedicado para usar la GPU desde los notebooks, añadir la extensión `jupyterlab-git` para versionar tu trabajo, o pasar a JupyterHub si varias personas necesitan su propio entorno en el mismo servidor.