Skip to content

Commit 75a4209

Browse files
committed
Dockerfile v0.6.0
- using python:3.12-slim-bookworm - jupyter lab instead of notebook - update docker readme - push to hub.docker.com
1 parent 7e687b2 commit 75a4209

4 files changed

Lines changed: 143 additions & 89 deletions

File tree

docker/Dockerfile

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,76 @@
1-
# -------- Licence -------------------------------------------------------------
2-
# Dual license: MIT and Apache v2
1+
#
2+
# Dockerfile for OpEn/opengen
3+
# Dockerfile version: 0.6.0
4+
# Bundled Python package: opengen v0.10.0
35
#
46
# Copyright (c) 2017 Pantelis Sopasakis and Emil Fresk
5-
# ------------------------------------------------------------------------------
6-
7-
7+
#
8+
#
9+
#
810
# -------- Run Instructions ----------------------------------------------------
911
# Run the docker image and start a terminal to access it by running:
1012
#
11-
# $ docker run -p 8888:8888 -it alphaville/open
13+
# $ docker run -p 127.0.0.1:8888:8888 -it alphaville/open
1214
#
13-
# You will be able to access your Jupyter Notebook at http://localhost:8888/
14-
# without a password. To set a password, read the documentation.
15+
# You will be able to access JupyterLab at http://localhost:8888/lab
16+
# using Jupyter's default token authentication. To set a password, read the
17+
# documentation.
1518
#
16-
# ------------------------------------------------------------------------------
19+
#
20+
21+
FROM python:3.12-slim-bookworm
1722

18-
FROM debian:stable
23+
ARG OPENGEN_VERSION=0.10.0
1924

2025
# Labels for the docker image
2126
LABEL maintainer="Pantelis Sopasakis <[email protected]>" \
2227
license="MIT license" \
23-
description="Jupyter notebook for Optimization Engine (OpEn)"
28+
description="JupyterLab for Optimization Engine (OpEn)"
2429

2530
WORKDIR /open
26-
VOLUME /open
2731

28-
# Example Python notebook
29-
COPY example.ipynb /open/
32+
# Example notebook content bundled with the image
33+
COPY notebooks/ /open/notebooks/
3034

31-
ENV PATH="/root/.cargo/bin:${PATH}"
35+
ENV VIRTUAL_ENV=/venv
36+
ENV PATH="${VIRTUAL_ENV}/bin:/root/.cargo/bin:${PATH}"
3237

3338
# These commands are groupped into a separate RUN to faciliate
3439
# caching; it is unlikely that any of the following will change
3540
# in future versions of this docker image
3641
RUN apt-get update -y \
3742
&& apt-get -y --no-install-recommends install \
3843
build-essential \
44+
ca-certificates \
3945
curl \
40-
jupyter-notebook \
41-
python3 \
42-
python3-pip \
43-
python3-setuptools \
44-
python3-venv \
45-
&& curl https://sh.rustup.rs -sSf | bash -s -- -y \
46-
&& cd /; python3 -m venv venv \
47-
&& /bin/bash -c "source /venv/bin/activate && pip install wheel && pip install opengen && pip install jupyter" \
46+
&& curl https://sh.rustup.rs -sSf | bash -s -- -y --profile minimal \
47+
&& python -m pip install --no-cache-dir --upgrade "pip>=26.0.1" \
48+
&& python -m venv "${VIRTUAL_ENV}" \
49+
&& "${VIRTUAL_ENV}/bin/python" -m pip install --no-cache-dir --upgrade "pip>=26.0.1" wheel \
50+
&& "${VIRTUAL_ENV}/bin/python" -m pip install --no-cache-dir "opengen==${OPENGEN_VERSION}" "jupyterlab<5" \
51+
&& "${VIRTUAL_ENV}/bin/python" -m pip uninstall -y py \
4852
&& apt-get clean \
4953
&& rm -rf /var/lib/apt/lists/* \
50-
&& echo "source /venv/bin/activate" >> /root/.bashrc
54+
&& echo "source ${VIRTUAL_ENV}/bin/activate" >> /root/.bashrc
55+
56+
VOLUME /open
5157

5258
EXPOSE 8888
5359

5460
# Run the following command every time this docker image
5561
# is executed
56-
COPY start_jupyter_notebook.sh /
57-
RUN ["chmod", "+x", "/start_jupyter_notebook.sh"]
58-
CMD ["/bin/bash", "/start_jupyter_notebook.sh"]
62+
COPY start_jupyter_notebook.sh /usr/local/bin/start_jupyter_notebook.sh
63+
RUN ["chmod", "+x", "/usr/local/bin/start_jupyter_notebook.sh"]
64+
CMD ["/usr/local/bin/start_jupyter_notebook.sh"]
5965

6066

6167

6268
# -------- Build Instructions --------------------------------------------------
6369
# Build the docker image by running (for DEVELOPERS only):
6470
#
65-
# $ docker image build -t alphaville/open .
71+
# $ docker image build -t alphaville/open:0.6.0 .
6672
#
67-
# from within the base directory of this project.
73+
# from within the docker directory of this project.
6874
#
6975
#
7076
# ------------------------------------------------------------------------------

docker/README.md

Lines changed: 71 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,117 @@
1-
# OpEn Jupyter Notebook
1+
# OpEn JupyterLab Docker Image
22

3-
Hmm.. that [OpEn](https://alphaville.github.io/optimization-engine/) framework looks really cool, but I'm too lazy to spend two minutes to [install](https://alphaville.github.io/optimization-engine/docs/installation) it!
3+
This directory contains the Docker image used to try OpEn quickly from a browser-based Python environment.
44

5-
## TaDa...
5+
The current Dockerfile and Docker image version documented here is `0.6.0`.
6+
This image bundles the Python package `opengen==0.10.0`.
67

7-
You can now download this docker image using
8+
## What is in the image?
9+
10+
The image is built from `python:3.12-slim-bookworm` and contains:
11+
12+
- Python 3.12 in a virtual environment at `/venv`
13+
- `opengen==0.10.0`
14+
- JupyterLab
15+
- Rust installed through `rustup`
16+
- Example notebooks copied into `/open/notebooks`
17+
18+
## Pull and run the image
819

920
```console
10-
docker pull alphaville/open
21+
docker pull alphaville/open:0.6.0
22+
docker run --name open-jupyter -p 127.0.0.1:8888:8888 -it alphaville/open:0.6.0
1123
```
1224

13-
and then run it with
25+
Open JupyterLab at:
26+
27+
- `http://127.0.0.1:8888/lab`
28+
29+
By default, the container starts with Jupyter's token authentication enabled. The token is printed in the container logs.
30+
31+
To see the token:
1432

1533
```console
16-
docker run --name open-jupyter -p 8888:8888 -it alphaville/open
34+
docker logs open-jupyter
1735
```
1836

19-
Note that this will create a docker container with name `open-jupyter`. If you stop it, you can restart it with (don't do `docker run` again)
37+
If you stop the container, restart it with:
2038

2139
```console
2240
docker start -ai open-jupyter
2341
```
2442

25-
## What it does
26-
27-
It starts a Jupyter Notebook at [localhost:8888](http://localhost:8888) without a password.
43+
## Password-based access
2844

29-
## What's in the docker image?
45+
To run JupyterLab with a password instead of the default token, provide a hashed password through `JUPYTER_NOTEBOOK_PASSWORD`.
3046

31-
This docker image is build from `debian:stable` and contains:
32-
33-
- A virtual environment (with Python 3)
34-
- Opengen [v0.8.0](https://github.com/alphaville/optimization-engine/releases/tag/opengen-0.8.0)
35-
- The [latest version](https://crates.io/crates/optimization_engine) of the OpEn rust solver is installed automatically
36-
- Jupyter notebook (runs automatically when the image runs)
47+
```console
48+
docker run \
49+
--name open-jupyter \
50+
-e JUPYTER_NOTEBOOK_PASSWORD=... \
51+
-p 127.0.0.1:8888:8888 \
52+
-it alphaville/open:0.6.0
53+
```
3754

55+
For password hashing instructions, see the Jupyter documentation:
3856

39-
## How to open a terminal into the docker image
57+
- https://jupyter-server.readthedocs.io/en/latest/operators/public-server.html
4058

41-
Just
59+
## Working with notebooks
4260

43-
```console
44-
docker exec -it open-jupyter bash
45-
```
61+
The bundled example notebook is stored in this repository under:
4662

47-
This will open a bash shell to the docker image with name `open-jupyter`; this is the name we specified above when we ran the image (using `--name open-jupyter`). In this bash shell, the virtual environment on which the Jupyter notebook is running is enabled by default.
63+
- `docker/notebooks/example.ipynb`
4864

65+
Inside the container it is available under:
4966

50-
### How to run with specified volume
67+
- `/open/notebooks/example.ipynb`
5168

52-
Firstly, you need to create a volume. You only need to do this once (unless you want to create different volumes). As an example, let us create a docker volume with name `OpEnVolume`:
69+
To keep your own notebooks between container runs, mount a volume onto `/open`:
5370

5471
```console
5572
docker volume create OpEnVolume
73+
docker run --name open-jupyter \
74+
--mount source=OpEnVolume,destination=/open \
75+
-p 127.0.0.1:8888:8888 \
76+
-it alphaville/open:0.6.0
5677
```
5778

58-
Next, let us run the image `alphaville/open:0.5.0` with the above volume:
79+
## Open a shell in the container
5980

6081
```console
61-
docker run --name open-jupyter \
62-
--mount source=OpEnVolume,destination=/open \
63-
-p 8888:8888 \
64-
-it alphaville/open:0.5.0
82+
docker exec -it open-jupyter bash
6583
```
6684

67-
## Set a password
85+
The virtual environment is available at `/venv`.
6886

69-
To set up a password for your Python Notebook:
87+
## Maintainer Notes
7088

71-
- [Hash your password](https://jupyter-notebook.readthedocs.io/en/stable/public_server.html#hashed-pw)
72-
- Run your docker image with:
89+
Build the image from within the `docker/` directory:
7390

91+
```console
92+
docker image build -t alphaville/open:0.6.0 .
7493
```
75-
docker run -e JUPYTER_NOTEBOOK_PASSWORD=... -p 8888:8888 -it alphaville/open
94+
95+
You can also build it from the repository root:
96+
97+
```console
98+
docker image build -t alphaville/open:0.6.0 -f docker/Dockerfile docker
7699
```
77100

78-
For example, let's say you want to set the password **open**. Then do
101+
Before publishing, do a quick smoke test:
79102

80103
```console
81-
docker run \
82-
-e JUPYTER_NOTEBOOK_PASSWORD=sha1:898ca689bf37:2ee883bfd6ffe82a749a86e37964700bd06a2ff9 \
83-
-p 8888:8888 -it alphaville/open
104+
docker run --rm -p 127.0.0.1:8888:8888 alphaville/open:0.6.0
84105
```
85106

107+
Then push the tag you built:
86108

109+
```console
110+
docker push alphaville/open:0.6.0
111+
```
112+
113+
If you want to check the bundled Python package version inside the image, run:
114+
115+
```console
116+
docker run --rm --entrypoint /venv/bin/python alphaville/open:0.6.0 -c "from importlib.metadata import version; print(version('opengen'))"
117+
```
Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
{
22
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": null,
6+
"metadata": {},
7+
"outputs": [],
8+
"source": [
9+
"import opengen as og\n",
10+
"import casadi.casadi as cs"
11+
]
12+
},
313
{
414
"cell_type": "markdown",
515
"metadata": {},
@@ -27,9 +37,6 @@
2737
"metadata": {},
2838
"outputs": [],
2939
"source": [
30-
"import opengen as og\n",
31-
"import casadi.casadi as cs\n",
32-
"\n",
3340
"# Build parametric optimizer\n",
3441
"# ------------------------------------\n",
3542
"u = cs.SX.sym(\"u\", 5) # decision variables\n",
@@ -84,7 +91,7 @@
8491
" .with_penalty_weight_update_factor(5)\n",
8592
"builder = og.builder.OpEnOptimizerBuilder(problem, meta,\n",
8693
" build_config, solver_config)\n",
87-
"builder.build()"
94+
"_ = builder.build()"
8895
]
8996
},
9097
{

docker/start_jupyter_notebook.sh

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,30 @@
11
#!/bin/bash
2-
# Shell script that starts the Jupyter Python Notebook
3-
# in the docker container
2+
# Shell script that starts JupyterLab in the docker container
43

5-
if [ -z "$JUPYTER_NOTEBOOK_PASSWORD" ]
6-
then
7-
echo "No Jupyter Notebook password provided - starting in unsafe mode"
8-
echo "Set password using -e JUPYTER_NOTEBOOK_PASSWORD={sha of password}"
9-
/venv/bin/jupyter notebook \
10-
--port=8888 --no-browser \
11-
--ip=0.0.0.0 --allow-root \
12-
--NotebookApp.password='' --NotebookApp.token=''
13-
else
14-
echo "Jupyter Notebook password provided by user"
15-
/venv/bin/jupyter notebook \
16-
--port=8888 --no-browser \
17-
--ip=0.0.0.0 --allow-root \
18-
--NotebookApp.password=$JUPYTER_NOTEBOOK_PASSWORD
4+
set -euo pipefail
5+
6+
JUPYTER_ARGS=(
7+
lab
8+
--ServerApp.root_dir=/open
9+
--port=8888
10+
--no-browser
11+
--ip=0.0.0.0
12+
--allow-root
13+
)
14+
15+
if [ -n "${JUPYTER_NOTEBOOK_PASSWORD:-}" ]; then
16+
echo "Starting JupyterLab with password authentication"
17+
exec /venv/bin/jupyter "${JUPYTER_ARGS[@]}" \
18+
--ServerApp.password="${JUPYTER_NOTEBOOK_PASSWORD}" \
19+
--ServerApp.token=''
20+
fi
21+
22+
if [ -n "${JUPYTER_NOTEBOOK_TOKEN:-}" ]; then
23+
echo "Starting JupyterLab with token authentication"
24+
exec /venv/bin/jupyter "${JUPYTER_ARGS[@]}" \
25+
--ServerApp.token="${JUPYTER_NOTEBOOK_TOKEN}"
1926
fi
2027

28+
echo "No password provided - starting JupyterLab with default token authentication"
29+
echo "Set JUPYTER_NOTEBOOK_PASSWORD to use password-only authentication"
30+
exec /venv/bin/jupyter "${JUPYTER_ARGS[@]}"

0 commit comments

Comments
 (0)