JupyterLab
Web-based environment for interactive and reproducible computing
JupyterLab is a web-based environment for interactive notebooks, code, terminals and data visualizations. It targets data scientists and researchers wanting a reproducible computing workspace on their own server. It is deployed via Docker, pip or conda.
Key features
- Interactive notebook interface
- Multi-language kernels
- Integrated terminals and editors
- Extension ecosystem
Pros & cons
Strengths
- Rich interactive notebooks
- Huge extension ecosystem
- Multi-language kernel support
Trade-offs
- Multi-user needs JupyterHub
- Extension compatibility churn
JupyterLab replaces
Last reviewed Sep 13, 2026 · 813 words
Treat JupyterLab as what it is: a web page that runs arbitrary code as the user who started it, on the machine it runs on. Everything about self-hosting it follows from that. It is superb as a personal workbench, a permanent Python or R environment on a box with more RAM than your laptop, reachable from any browser. It is a disaster on a public port, and it is the wrong tool the moment a second person needs their own login, because JupyterLab has one user and one process by design.
One user, one token, one process
Out of the box the server listens on port 8888 and prints a random token to the log; you paste it once and the browser keeps a cookie. That is the authentication, and it is fine for one person. Set a password instead with jupyter server password if the token dance annoys you. What does not exist is a second account: a colleague using the same URL gets your files, your kernels and your shell. Multi-user means JupyterHub, which spawns a private JupyterLab per person and fronts them with real logins. It is a heavier install and the right answer for a lab or a classroom, not for one engineer.
Start from the Docker Stacks image, not from pip
pip install jupyterlab on the host works and then rots: the environment drifts, a system Python upgrade breaks a kernel, and you are reinstalling on a Sunday. The Jupyter Docker Stacks images bundle a pinned Python, conda and a working kernel, and the scipy variant adds pandas, matplotlib and the usual suspects:
services:
jupyter:
image: quay.io/jupyter/scipy-notebook:latest
ports:
- "8888:8888"
volumes:
- ./notebooks:/home/jovyan/work
environment:
- JUPYTER_TOKEN=change-this-long-string
restart: unless-stopped
The container user is jovyan with UID 1000; if the mounted folder is owned by someone else, the first notebook save fails with a permissions error, which is the most common first-day problem. Anything you pip install inside a running container vanishes on recreation, so the second time you need a package, add a Dockerfile with a RUN pip install line. A bare install fits in 512 MB, but a kernel holding a real dataframe takes whatever the data takes; plan for the data, not for Jupyter.
Where it sits: next to the GPU, behind the tailnet
The reason to run this on a server rather than a laptop is the server's resources: 64 GB of RAM, a GPU, a fast disk holding the dataset. Mount the data read-only into the container, and if there is a GPU, use the pytorch-notebook image variant with the NVIDIA runtime. A notebook talking to a local model through Ollama on the same host is a good pairing and a good reason to have both. For access, put it on the tailnet and nowhere else: Tailscale gives you a URL you can open from anywhere and an attacker cannot see. If it must live on a domain, it goes behind a reverse proxy with TLS and the token, and the proxy must pass WebSockets or every kernel will show as disconnected.
Extensions, and the churn that comes with them
The extension system is why JupyterLab rather than the classic notebook: a Git panel, a language server for real autocompletion, a variable inspector, themes. The cost is the second con in its catalogue entry: each JupyterLab major version has broken a share of extensions, and a container rebuild can leave a panel silently missing. Keep the extension list short and pinned in the Dockerfile. If what you actually want is an editor with a terminal that also opens notebooks, code-server is the better fit; it runs .ipynb files too, less elegantly.
Colab still wins on one thing
Google Colab is what most people are replacing, and the honest comparison in the Colab alternatives list is short. You gain a persistent environment, no session timeouts, no file uploads every morning, and private data that never leaves your network. You lose the free GPU. If your work needs a T4 twice a month and you do not own one, self-hosting JupyterLab does not remove Colab from your life; it moves the CPU work home and leaves the GPU runs where they were.
What I'd do
The scipy-notebook image with a small Dockerfile for extra packages, notebooks in a mounted, backed-up folder, a fixed JUPYTER_TOKEN, and port 8888 reachable only over Tailscale. One user. When a second person appears, JupyterHub on the same box rather than a shared token. It is the best interactive environment available to anyone who thinks in data rather than in files, and the security posture is the only part of it that needs discipline.
Compare JupyterLab
1 head-to-head comparisons.
Similar ides & code editors apps
code-server
IDEs & Code EditorsRun VS Code in the browser on your server
Replaces GitHub Codespaces
Eclipse Theia
IDEs & Code EditorsCloud and desktop IDE platform
Replaces VS Code, GitHub Codespaces
Coder
IDEs & Code EditorsSelf-hosted cloud development environments
Replaces GitHub Codespaces, Gitpod
DevPod
IDEs & Code EditorsCodespaces but open-source and self-hosted
Replaces GitHub Codespaces
Gitpod
IDEs & Code EditorsAutomated, ready-to-code development environments
Replaces GitHub Codespaces
JupyterHub
IDEs & Code EditorsMulti-user server for Jupyter notebooks
Replaces Google Colab, Deepnote