Skip to content

Commit b418b67

Browse files
authored
Merge pull request #1575 from romainx/fix-1217-1
Jupyter Notebook deprecation -> default to JupyterLab
2 parents f162376 + c954633 commit b418b67

File tree

9 files changed

+114
-76
lines changed

9 files changed

+114
-76
lines changed

Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ cont-rm-all: ## remove all containers
128128

129129

130130

131-
dev/%: DARGS?=-e JUPYTER_ENABLE_LAB=yes
132131
dev/%: PORT?=8888
133132
dev/%: ## run a foreground container for a stack
134133
docker run -it --rm -p $(PORT):8888 $(DARGS) $(OWNER)/$(notdir $@)

README.md

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,39 +16,39 @@ by simply clicking the preceding link.
1616
The image used in binder was last updated on 22 May 2021.
1717
Otherwise, three examples below may help you get started if you [have Docker installed](https://docs.docker.com/install/),
1818
know [which Docker image](https://jupyter-docker-stacks.readthedocs.io/en/latest/using/selecting.html) you want to use
19-
and want to launch a single Jupyter Notebook server in a container.
19+
and want to launch a single Jupyter Server in a container.
2020

2121
The [User Guide on ReadTheDocs](https://jupyter-docker-stacks.readthedocs.io/) describes additional uses and features in detail.
2222

2323
**Example 1:** This command pulls the `jupyter/scipy-notebook` image tagged `33add21fab64` from Docker Hub if it is not already present on the local host.
24-
It then starts a container running a Jupyter Notebook server and exposes the server on host port 8888.
24+
It then starts a container running a Jupyter Server and exposes the server on host port 8888.
2525
The server logs appear in the terminal.
26-
Visiting `http://<hostname>:8888/?token=<token>` in a browser loads the Jupyter Notebook dashboard page,
26+
Visiting `http://<hostname>:8888/?token=<token>` in a browser loads JupyterLab,
2727
where `hostname` is the name of the computer running docker and `token` is the secret token printed in the console.
28-
The container remains intact for restart after the notebook server exits.
28+
The container remains intact for restart after the Jupyter Server exits.
2929

3030
```bash
3131
docker run -p 8888:8888 jupyter/scipy-notebook:33add21fab64
3232
```
3333

3434
**Example 2:** This command performs the same operations as **Example 1**, but it exposes the server on host port 10000 instead of port 8888.
35-
Visiting `http://<hostname>:10000/?token=<token>` in a browser loads Jupyter Notebook server,
35+
Visiting `http://<hostname>:10000/?token=<token>` in a browser loads JupyterLab,
3636
where `hostname` is the name of the computer running docker and `token` is the secret token printed in the console.
3737

3838
```bash
3939
docker run -p 10000:8888 jupyter/scipy-notebook:33add21fab64
4040
```
4141

4242
**Example 3:** This command pulls the `jupyter/datascience-notebook` image tagged `33add21fab64` from Docker Hub if it is not already present on the local host.
43-
It then starts an _ephemeral_ container running a Jupyter Notebook server and exposes the server on host port 10000.
43+
It then starts an _ephemeral_ container running a Jupyter Server and exposes the server on host port 10000.
4444
The command mounts the current working directory on the host as `/home/jovyan/work` in the container.
4545
The server logs appear in the terminal.
4646
Visiting `http://<hostname>:10000/?token=<token>` in a browser loads JupyterLab,
4747
where `hostname` is the name of the computer running docker and `token` is the secret token printed in the console.
48-
Docker destroys the container after notebook server exit, but any files written to `~/work` in the container remain intact on the host.
48+
Docker destroys the container after Jupyter Server exit, but any files written to `~/work` in the container remain intact on the host.
4949

5050
```bash
51-
docker run --rm -p 10000:8888 -e JUPYTER_ENABLE_LAB=yes -v "${PWD}":/home/jovyan/work jupyter/datascience-notebook:33add21fab64
51+
docker run --rm -p 10000:8888 -v "${PWD}":/home/jovyan/work jupyter/datascience-notebook:33add21fab64
5252
```
5353

5454
## Contributing
@@ -76,13 +76,12 @@ We will happily grant additional permissions (e.g., ability to merge PRs) to any
7676

7777
## Jupyter Notebook Deprecation Notice
7878

79-
Following [Jupyter Notebook notice](https://github.com/jupyter/notebook#notice), we encourage users to transition to JupyterLab.
80-
This can be done by passing the environment variable `JUPYTER_ENABLE_LAB=yes` at container startup,
79+
Following [Jupyter Notebook notice](https://github.com/jupyter/notebook#notice), JupyterLab is now the default for all of the Jupyter Docker stack images.
80+
It is still possible to switch back to Jupyter Notebook (or to launch a different startup command).
81+
This can be done by passing the environment variable `DOCKER_STACKS_JUPYTER_CMD=notebook` (or any other valid `jupyter` command) at container startup,
8182
more information is available in the [documentation](https://jupyter-docker-stacks.readthedocs.io/en/latest/using/common.html#docker-options).
8283

83-
At some point, JupyterLab will become the default for all of the Jupyter Docker stack images, however a new environment variable will be introduced to switch back to Jupyter Notebook if needed.
84-
85-
After the change of default, and according to the Jupyter Notebook project status and its compatibility with JupyterLab,
84+
According to the Jupyter Notebook project status and its compatibility with JupyterLab,
8685
these Docker images may remove the classic Jupyter Notebook interface altogether in favor of another _classic-like_ UI built atop JupyterLab.
8786

8887
This change is tracked in the issue [#1217](https://github.com/jupyter/docker-stacks/issues/1217), please check its content for more information.

base-notebook/start-notebook.sh

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44

55
set -e
66

7+
# The Jupyter command to launch
8+
# JupyterLab by default
9+
DOCKER_STACKS_JUPYTER_CMD="${DOCKER_STACKS_JUPYTER_CMD:=lab}"
10+
711
if [[ -n "${JUPYTERHUB_API_TOKEN}" ]]; then
812
echo "WARNING: using start-singleuser.sh instead of start-notebook.sh to start a server associated with JupyterHub."
913
exec /usr/local/bin/start-singleuser.sh "$@"
@@ -14,11 +18,9 @@ if [[ "${RESTARTABLE}" == "yes" ]]; then
1418
wrapper="run-one-constantly"
1519
fi
1620

17-
if [[ -n "${JUPYTER_ENABLE_LAB}" ]]; then
18-
# shellcheck disable=SC1091,SC2086
19-
exec /usr/local/bin/start.sh ${wrapper} jupyter lab ${NOTEBOOK_ARGS} "$@"
20-
else
21-
echo "WARNING: Jupyter Notebook deprecation notice https://github.com/jupyter/docker-stacks#jupyter-notebook-deprecation-notice."
22-
# shellcheck disable=SC1091,SC2086
23-
exec /usr/local/bin/start.sh ${wrapper} jupyter notebook ${NOTEBOOK_ARGS} "$@"
21+
if [[ -v JUPYTER_ENABLE_LAB ]]; then
22+
echo "WARNING: JUPYTER_ENABLE_LAB is ignored, use DOCKER_STACKS_JUPYTER_CMD if you want to change the command used to start the server"
2423
fi
24+
25+
# shellcheck disable=SC1091,SC2086
26+
exec /usr/local/bin/start.sh ${wrapper} jupyter ${DOCKER_STACKS_JUPYTER_CMD} ${NOTEBOOK_ARGS} "$@"

base-notebook/test/test_container_options.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ def test_cli_args(container: TrackedContainer, http_client: requests.Session) ->
2323
warnings = [
2424
warning for warning in logs.split("\n") if warning.startswith("WARNING")
2525
]
26-
assert len(warnings) == 1
27-
assert warnings[0].startswith("WARNING: Jupyter Notebook deprecation notice")
26+
assert not warnings
2827
assert "login_submit" not in resp.text
2928

3029

@@ -49,8 +48,7 @@ def test_unsigned_ssl(
4948
warnings = [
5049
warning for warning in logs.split("\n") if warning.startswith("WARNING")
5150
]
52-
assert len(warnings) == 1
53-
assert warnings[0].startswith("WARNING: Jupyter Notebook deprecation notice")
51+
assert not warnings
5452

5553

5654
def test_uid_change(container: TrackedContainer) -> None:

base-notebook/test/test_start_container.py

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,56 +2,77 @@
22
# Distributed under the terms of the Modified BSD License.
33

44
import logging
5+
from typing import Optional
56
import pytest
67
import requests
8+
import re
9+
import time
710

811
from conftest import TrackedContainer
912

1013
LOGGER = logging.getLogger(__name__)
1114

1215

1316
@pytest.mark.parametrize(
14-
"env,expected_server",
17+
"env,expected_command,expected_start,expected_warnings",
1518
[
16-
(["JUPYTER_ENABLE_LAB=yes"], "lab"),
17-
(None, "notebook"),
19+
(
20+
["JUPYTER_ENABLE_LAB=yes"],
21+
"jupyter lab",
22+
True,
23+
["WARNING: JUPYTER_ENABLE_LAB is ignored"],
24+
),
25+
(None, "jupyter lab", True, []),
26+
(["DOCKER_STACKS_JUPYTER_CMD=lab"], "jupyter lab", True, []),
27+
(["RESTARTABLE=yes"], "run-one-constantly jupyter lab", True, []),
28+
(["DOCKER_STACKS_JUPYTER_CMD=notebook"], "jupyter notebook", True, []),
29+
(["DOCKER_STACKS_JUPYTER_CMD=server"], "jupyter server", True, []),
30+
(["DOCKER_STACKS_JUPYTER_CMD=nbclassic"], "jupyter nbclassic", True, []),
31+
(
32+
["JUPYTERHUB_API_TOKEN=my_token"],
33+
"jupyterhub-singleuser",
34+
False,
35+
["WARNING: using start-singleuser.sh"],
36+
),
1837
],
1938
)
2039
def test_start_notebook(
2140
container: TrackedContainer,
2241
http_client: requests.Session,
23-
env,
24-
expected_server: str,
42+
env: Optional[list[str]],
43+
expected_command: str,
44+
expected_start: bool,
45+
expected_warnings: list[str],
2546
) -> None:
2647
"""Test the notebook start-notebook script"""
2748
LOGGER.info(
28-
f"Test that the start-notebook launches the {expected_server} server from the env {env} ..."
49+
f"Test that the start-notebook launches the {expected_command} server from the env {env} ..."
2950
)
3051
c = container.run(
3152
tty=True,
3253
environment=env,
3354
command=["start-notebook.sh"],
3455
)
35-
resp = http_client.get("http://localhost:8888")
56+
# sleeping some time to let the server start
57+
time.sleep(3)
3658
logs = c.logs(stdout=True).decode("utf-8")
3759
LOGGER.debug(logs)
38-
assert "ERROR" not in logs
39-
if expected_server != "notebook":
40-
assert "WARNING" not in logs
41-
else:
42-
warnings = [
43-
warning for warning in logs.split("\n") if warning.startswith("WARNING")
44-
]
45-
assert len(warnings) == 1
46-
assert warnings[0].startswith("WARNING: Jupyter Notebook deprecation notice")
47-
assert resp.status_code == 200, "Server is not listening"
60+
# checking that the expected command is launched
4861
assert (
49-
f"Executing the command: jupyter {expected_server}" in logs
50-
), f"Not the expected command (jupyter {expected_server}) was launched"
51-
# Checking warning messages
52-
if not env:
53-
msg = "WARNING: Jupyter Notebook deprecation notice"
54-
assert msg in logs, f"Expected warning message {msg} not printed"
62+
f"Executing the command: {expected_command}" in logs
63+
), f"Not the expected command ({expected_command}) was launched"
64+
# checking errors and warnings in logs
65+
assert "ERROR" not in logs, "ERROR(s) found in logs"
66+
for exp_warning in expected_warnings:
67+
assert exp_warning in logs, f"Expected warning {exp_warning} not found in logs"
68+
warnings = re.findall(r"^WARNING", logs, flags=re.MULTILINE)
69+
assert len(expected_warnings) == len(
70+
warnings
71+
), "Not found the number of expected warnings in logs"
72+
# checking if the server is listening
73+
if expected_start:
74+
resp = http_client.get("http://localhost:8888")
75+
assert resp.status_code == 200, "Server is not listening"
5576

5677

5778
def test_tini_entrypoint(

docs/index.rst

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,34 +15,34 @@ You can try a `relatively recent build of the jupyter/base-notebook image on myb
1515
by simply clicking the preceding link.
1616
Otherwise, three examples below may help you get started if you `have Docker installed <https://docs.docker.com/install/>`_,
1717
know :doc:`which Docker image <using/selecting>` you want to use
18-
and want to launch a single Jupyter Notebook server in a container.
18+
and want to launch a single Jupyter Server in a container.
1919

2020
The other pages in this documentation describe additional uses and features in detail.
2121

2222
**Example 1:** This command pulls the ``jupyter/scipy-notebook`` image tagged ``33add21fab64`` from Docker Hub if it is not already present on the local host.
23-
It then starts a container running a Jupyter Notebook server and exposes the server on host port 8888.
23+
It then starts a container running a Jupyter Server and exposes the server on host port 8888.
2424
The server logs appear in the terminal.
25-
Visiting ``http://<hostname>:8888/?token=<token>`` in a browser loads the Jupyter Notebook dashboard page,
25+
Visiting ``http://<hostname>:8888/?token=<token>`` in a browser loads JupyterLab,
2626
where ``hostname`` is the name of the computer running docker and ``token`` is the secret token printed in the console.
27-
The container remains intact for restart after the notebook server exits.::
27+
The container remains intact for restart after the Jupyter Server exits.::
2828

2929
docker run -p 8888:8888 jupyter/scipy-notebook:33add21fab64
3030

3131
**Example 2:** This command performs the same operations as **Example 1**, but it exposes the server on host port 10000 instead of port 8888.
32-
Visiting ``http://<hostname>:10000/?token=<token>`` in a browser loads Jupyter Notebook server,
32+
Visiting ``http://<hostname>:10000/?token=<token>`` in a browser loads JupyterLab,
3333
where ``hostname`` is the name of the computer running docker and ``token`` is the secret token printed in the console.::
3434

3535
docker run -p 10000:8888 jupyter/scipy-notebook:33add21fab64
3636

3737
**Example 3:** This command pulls the ``jupyter/datascience-notebook`` image tagged ``33add21fab64`` from Docker Hub if it is not already present on the local host.
38-
It then starts an *ephemeral* container running a Jupyter Notebook server and exposes the server on host port 10000.
38+
It then starts an *ephemeral* container running a Jupyter Server and exposes the server on host port 10000.
3939
The command mounts the current working directory on the host as ``/home/jovyan/work`` in the container.
4040
The server logs appear in the terminal.
4141
Visiting ``http://<hostname>:10000/lab?token=<token>`` in a browser loads JupyterLab,
4242
where ``hostname`` is the name of the computer running docker and ``token`` is the secret token printed in the console.
43-
Docker destroys the container after notebook server exit, but any files written to ``~/work`` in the container remain intact on the host.::
43+
Docker destroys the container after Jupyter Server exit, but any files written to ``~/work`` in the container remain intact on the host.::
4444

45-
docker run --rm -p 10000:8888 -e JUPYTER_ENABLE_LAB=yes -v "${PWD}":/home/jovyan/work jupyter/datascience-notebook:33add21fab64
45+
docker run --rm -p 10000:8888 -v "${PWD}":/home/jovyan/work jupyter/datascience-notebook:33add21fab64
4646

4747
CPU Architectures
4848
-----------------

docs/using/common.md

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ You do so by passing arguments to the `docker run` command.
6969
(The `start-notebook.sh` script will `su ${NB_USER}` after adding `${NB_USER}` to sudoers.)
7070
**You should only enable `sudo` if you trust the user or if the container is running on an isolated host.**
7171
- `-e GEN_CERT=yes` - Instructs the startup script to generates a self-signed SSL certificate and configure Jupyter Notebook to use it to accept encrypted HTTPS connections.
72-
- `-e JUPYTER_ENABLE_LAB=yes` - Instructs the startup script to run `jupyter lab` instead of the default `jupyter notebook` command.
72+
- `-e DOCKER_STACKS_JUPYTER_CMD=<jupyter command>` - Instructs the startup script to run `jupyter ${DOCKER_STACKS_JUPYTER_CMD}` instead of the default `jupyter lab` command.
73+
See [Switching back to classic notebook or using a different startup command][switch_back] for available options.
7374
Useful in container orchestration environments where setting environment variables is easier than change command line parameters.
7475
- `-e RESTARTABLE=yes` - Runs Jupyter in a loop so that quitting Jupyter does not cause the container to exit.
7576
This may be useful when you need to install extensions that require restarting Jupyter.
@@ -130,7 +131,41 @@ For additional information about using SSL, see the following:
130131

131132
## Alternative Commands
132133

133-
### start.sh
134+
### Switching back to classic notebook or using a different startup command
135+
136+
JupyterLab built on top of Jupyter Server is now the default for all images of the stack.
137+
However, it is still possible to switch back to the classic notebook or to use a different startup command.
138+
This can be done by setting the environment variable `DOCKER_STACKS_JUPYTER_CMD` at container startup.
139+
The table below shows some options.
140+
141+
| `DOCKER_STACKS_JUPYTER_CMD` | Backend | Frontend |
142+
| --------------------------- | ---------------- | ---------------- |
143+
| `lab` (default) | Jupyter Server | JupyterLab |
144+
| `notebook` | Jupyter Notebook | Jupyter Notebook |
145+
| `nbclassic` | Jupyter Server | Jupyter Notebook |
146+
| `server` | Jupyter Server | None |
147+
| `retro`\* | Jupyter Server | RetroLab |
148+
149+
Notes:
150+
151+
- \*Not installed at this time, but it could be the case in the future or in a community stack.
152+
- Any other valid `jupyter` command that starts the Jupyter server can be used.
153+
154+
Example:
155+
156+
```bash
157+
# Run Jupyter Notebook classic
158+
docker run -it --rm -p 8888:8888 -e DOCKER_STACKS_JUPYTER_CMD=notebook \
159+
jupyter/base-notebook
160+
# Executing the command: jupyter notebook ...
161+
162+
# Run Jupyter Notebook on Jupyter Server
163+
docker run -it --rm -p 8888:8888 -e DOCKER_STACKS_JUPYTER_CMD=nbclassic \
164+
jupyter/base-notebook
165+
# Executing the command: jupyter nbclassic ...
166+
```
167+
168+
### `start.sh`
134169

135170
The `start-notebook.sh` script actually inherits most of its option handling capability from a more generic `start.sh` script.
136171
The `start.sh` script supports all of the features described above, but allows you to specify an arbitrary command to execute.
@@ -196,3 +231,5 @@ mamba install --quiet --yes humanize && \
196231
fix-permissions "${CONDA_DIR}" && \
197232
fix-permissions "/home/${NB_USER}"
198233
```
234+
235+
[switch_back]: common.html#switching-back-to-classic-notebook-or-using-a-different-startup-command

docs/using/recipes.md

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -137,14 +137,6 @@ ENV PATH "${CONDA_DIR}/envs/${conda_env}/bin:${PATH}"
137137
# ENV CONDA_DEFAULT_ENV ${conda_env}
138138
```
139139

140-
## Run JupyterLab
141-
142-
JupyterLab is preinstalled as a notebook extension starting in tag
143-
[c33a7dc0eece](https://github.com/jupyter/docker-stacks/pull/355).
144-
145-
Run jupyterlab using a command such as
146-
`docker run -it --rm -p 8888:8888 -e JUPYTER_ENABLE_LAB=yes jupyter/datascience-notebook`
147-
148140
## Dask JupyterLab Extension
149141

150142
[Dask JupyterLab Extension](https://github.com/dask/dask-labextension) provides a JupyterLab extension to manage Dask clusters, as well as embed Dask's dashboard plots directly into JupyterLab panes.

examples/openshift/README.md

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -127,16 +127,6 @@ To delete the notebook instance, run `oc delete` using a label selector for the
127127
oc delete all,configmap --selector app=mynotebook
128128
```
129129

130-
## Enabling Jupyter Lab Interface
131-
132-
To enable the Jupyter Lab interface for a deployed notebook set the `JUPYTER_ENABLE_LAB` environment variable.
133-
134-
```bash
135-
oc set env dc/mynotebook JUPYTER_ENABLE_LAB=true
136-
```
137-
138-
Setting the environment variable will trigger a new deployment and the Jupyter Lab interface will be enabled.
139-
140130
## Adding Persistent Storage
141131

142132
You can upload notebooks and other files using the web interface of the notebook.

0 commit comments

Comments
 (0)