---
title: JupyterLab
description: Run token-authenticated notebooks in an isolated Python environment
icon: "flask"
---

<Tooltip tip="This example publishes JupyterLab to a port on the computer running the CLI, which is not available on microsandbox cloud."><span className="msb-badge-local">Local-only <Icon icon="circle-info" size={11} /></span></Tooltip>

This example installs JupyterLab into a Python microVM, stores notebooks in a named volume, and exposes the server only on host loopback.

## Run JupyterLab

<Steps>
<Step title="Start JupyterLab">

Set a temporary token in the host shell:

<CodeGroup>
```sh macOS & Linux
export JUPYTER_TOKEN="$(openssl rand -hex 24)"
```

```powershell Windows
$bytes = New-Object byte[] 24
$rng = [Security.Cryptography.RandomNumberGenerator]::Create()
$rng.GetBytes($bytes)
$rng.Dispose()
$env:JUPYTER_TOKEN = -join ($bytes | ForEach-Object { $_.ToString('x2') })
```
</CodeGroup>

Start the server:

<CodeGroup>
```sh macOS & Linux
msb run -d --name jupyter-demo --replace \
  --cpus 2 --memory 2G --root-disk 4G \
  -p 127.0.0.1:8888:8888 \
  -e JUPYTER_TOKEN="$JUPYTER_TOKEN" \
  --mount-named jupyter-notebooks:/workspace \
  --workdir /workspace \
  python:3.13-slim -- sh -lc '
    pip install --no-cache-dir jupyterlab==4.6.2 &&
    exec jupyter lab \
      --ip=0.0.0.0 \
      --port=8888 \
      --no-browser \
      --allow-root \
      --IdentityProvider.token="$JUPYTER_TOKEN"
  '
```

```powershell Windows
msb run -d --name jupyter-demo --replace `
  --cpus 2 --memory 2G --root-disk 4G `
  -p 127.0.0.1:8888:8888 `
  -e "JUPYTER_TOKEN=$env:JUPYTER_TOKEN" `
  --mount-named jupyter-notebooks:/workspace `
  --workdir /workspace `
  python:3.13-slim -- sh -lc '
    pip install --no-cache-dir jupyterlab==4.6.2 &&
    exec jupyter lab \
      --ip=0.0.0.0 \
      --port=8888 \
      --no-browser \
      --allow-root \
      --IdentityProvider.token="$JUPYTER_TOKEN"
  '
```
</CodeGroup>

Open `http://127.0.0.1:8888/lab?token=<token>` in your browser and replace `<token>` with the value generated above.

</Step>

<Step title="Verify the service">

Check the authenticated API from the host:

<CodeGroup>
```sh macOS & Linux
curl -sS "http://127.0.0.1:8888/api?token=$JUPYTER_TOKEN" | head
```

```powershell Windows
curl.exe -sS "http://127.0.0.1:8888/api?token=$env:JUPYTER_TOKEN" | Select-Object -First 10
```
</CodeGroup>

Then inspect the recent server output:

```sh
msb logs --tail 20 jupyter-demo
```

The logs show Jupyter Server listening on guest port 8888. Notebooks saved under `/workspace` remain in `jupyter-notebooks` after the sandbox is removed.

<Warning>
  The token is visible to the guest and to processes that can inspect the host command environment. Use the [secrets workflow](/sandboxes/secrets) for production credentials, retain the loopback bind, and place a TLS-terminating authenticated proxy in front of any remote deployment.
</Warning>

</Step>

<Step title="Clean up">

Remove the sandbox:

```sh
msb rm -f jupyter-demo
```

Remove persisted notebooks only when you no longer need them:

```sh
msb volume rm jupyter-notebooks
```

Clear the token from the host shell:

<CodeGroup>
```sh macOS & Linux
unset JUPYTER_TOKEN
```

```powershell Windows
Remove-Item Env:JUPYTER_TOKEN
```
</CodeGroup>

Keep `jupyter-notebooks` if you want to retain the notebooks.

</Step>
</Steps>
