Skip to content

Commit 0d324bc

Browse files
imiroMuhammad Aji Muharrompre-commit-ci[bot]mathbunnyru
authored
Parameterize healthcheck by internal port (#1859)
* Use the JUPYTER_PORT environment variable to configure server port - Remove port setting in jupyter_server_config.py - Declare the $JUPYTER_PORT env on the base Dockerfile - Use it for HEALTHCHECK * Add test case for JUPYTER_PORT env variable * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update documentation * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update style * Better wording * Better wording * Add test for custom internal port * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Parametrize internal port test case * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Try to fix test * Better tests Co-authored-by: Muhammad Aji Muharrom <ajimuharrom@uchicago.edu> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com> Co-authored-by: Ayaz Salikhov <mathbunnyru@gmail.com>
1 parent e014bb8 commit 0d324bc

File tree

5 files changed

+51
-5
lines changed

5 files changed

+51
-5
lines changed

base-notebook/Dockerfile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ RUN mamba install --quiet --yes \
4747
fix-permissions "${CONDA_DIR}" && \
4848
fix-permissions "/home/${NB_USER}"
4949

50-
EXPOSE 8888
50+
ENV JUPYTER_PORT=8888
51+
EXPOSE $JUPYTER_PORT
5152

5253
# Configure container startup
5354
CMD ["start-notebook.sh"]
@@ -70,7 +71,7 @@ RUN sed -re "s/c.ServerApp/c.NotebookApp/g" \
7071
# https://github.com/jupyter/docker-stacks/issues/915#issuecomment-1068528799
7172
HEALTHCHECK --interval=5s --timeout=3s --start-period=5s --retries=3 \
7273
CMD wget -O- --no-verbose --tries=1 --no-check-certificate \
73-
http${GEN_CERT:+s}://localhost:8888${JUPYTERHUB_SERVICE_PREFIX:-/}api || exit 1
74+
http${GEN_CERT:+s}://localhost:${JUPYTER_PORT}${JUPYTERHUB_SERVICE_PREFIX:-/}api || exit 1
7475

7576
# Switch back to jovyan to avoid accidental container runs as root
7677
USER ${NB_UID}

base-notebook/jupyter_server_config.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
c = get_config() # noqa: F821
1111
c.ServerApp.ip = "0.0.0.0"
12-
c.ServerApp.port = 8888
1312
c.ServerApp.open_browser = False
1413

1514
# to output both image/svg+xml and application/pdf plot formats in the notebook file

docs/using/common.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,16 @@ You can pass [Jupyter server options](https://jupyter-server.readthedocs.io/en/l
2222
2. To set the [base URL](https://jupyter-server.readthedocs.io/en/latest/operators/public-server.html#running-the-notebook-with-a-customized-url-prefix) of the notebook server, you can run the following:
2323

2424
```bash
25-
docker run -it --rm -p 8888:8888 jupyter/base-notebook \
25+
docker run -it --rm -p 8888:8888 --no-healthcheck jupyter/base-notebook \
2626
start-notebook.sh --NotebookApp.base_url=/customized/url/prefix/
2727
```
2828

29+
Note: We pass the `--no-healthcheck` parameter when setting a custom `base_url` for the Jupyter server,
30+
because our current implementation for doing healthcheck assumes the `base_url` to be `/` (the default).
31+
Without using this parameter, the container may run, but it's state will be "unhealthy".
32+
Alternatively, you can [use your own command for healthcheck](https://docs.docker.com/engine/reference/run/#healthcheck)
33+
using the `--health-cmd` parameter.
34+
2935
## Docker Options
3036

3137
You may instruct the `start-notebook.sh` script to customize the container environment before launching the notebook server.
@@ -123,6 +129,8 @@ You do so by passing arguments to the `docker run` command.
123129
The variables are unset after the hooks have been executed but before the command provided to the startup script runs.
124130
- `-e NOTEBOOK_ARGS="--log-level='DEBUG' --dev-mode"` - Adds custom options to add to `jupyter` commands.
125131
This way, the user could use any option supported by `jupyter` subcommand.
132+
- `-e JUPYTER_PORT=8117` - Changes the port in the container that Jupyter is using to the value of the `${JUPYTER_PORT}` environment variable.
133+
This may be useful if you run multiple instances of Jupyter in swarm mode and want to use a different port for each instance.
126134

127135
## Startup Hooks
128136

tests/base-notebook/test_container_options.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,39 @@ def test_unsigned_ssl(
7878
assert "ERROR" not in logs
7979
warnings = TrackedContainer.get_warnings(logs)
8080
assert not warnings
81+
82+
83+
@pytest.mark.parametrize(
84+
"env",
85+
[
86+
{},
87+
{"JUPYTER_PORT": 1234, "DOCKER_STACKS_JUPYTER_CMD": "lab"},
88+
{"JUPYTER_PORT": 2345, "DOCKER_STACKS_JUPYTER_CMD": "notebook"},
89+
{"JUPYTER_PORT": 3456, "DOCKER_STACKS_JUPYTER_CMD": "server"},
90+
{"JUPYTER_PORT": 4567, "DOCKER_STACKS_JUPYTER_CMD": "nbclassic"},
91+
{"JUPYTER_PORT": 5678, "RESTARTABLE": "yes"},
92+
{"JUPYTER_PORT": 6789},
93+
{"JUPYTER_PORT": 7890, "DOCKER_STACKS_JUPYTER_CMD": "notebook"},
94+
],
95+
)
96+
def test_custom_internal_port(
97+
container: TrackedContainer,
98+
http_client: requests.Session,
99+
env: dict[str, str],
100+
) -> None:
101+
"""Container should be accessible from the host
102+
when using custom internal port"""
103+
host_port = find_free_port()
104+
internal_port = env.get("JUPYTER_PORT", 8888)
105+
running_container = container.run_detached(
106+
command=["start-notebook.sh", "--NotebookApp.token=''"],
107+
environment=env,
108+
ports={internal_port: host_port},
109+
)
110+
resp = http_client.get(f"http://localhost:{host_port}")
111+
resp.raise_for_status()
112+
logs = running_container.logs().decode("utf-8")
113+
LOGGER.debug(logs)
114+
assert "ERROR" not in logs
115+
warnings = TrackedContainer.get_warnings(logs)
116+
assert not warnings

tests/base-notebook/test_healthcheck.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@
1717
[
1818
None,
1919
["DOCKER_STACKS_JUPYTER_CMD=lab"],
20-
["RESTARTABLE=yes"],
2120
["DOCKER_STACKS_JUPYTER_CMD=notebook"],
2221
["DOCKER_STACKS_JUPYTER_CMD=server"],
2322
["DOCKER_STACKS_JUPYTER_CMD=nbclassic"],
23+
["RESTARTABLE=yes"],
24+
["JUPYTER_PORT=8171"],
25+
["JUPYTER_PORT=8117", "DOCKER_STACKS_JUPYTER_CMD=notebook"],
2426
],
2527
)
2628
def test_health(container: TrackedContainer, env: Optional[list[str]]) -> None:

0 commit comments

Comments
 (0)