Skip to content

Commit 0f5982c

Browse files
committed
Expand basic customizations tutorial
1 parent d420842 commit 0f5982c

File tree

1 file changed

+111
-51
lines changed
  • topics/teaching/tutorials/jbt-customization-1

1 file changed

+111
-51
lines changed

topics/teaching/tutorials/jbt-customization-1/tutorial.md

Lines changed: 111 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ Let's tear this command apart:
6767
| 127.0.0.1:8888:8888 | The argument for `-p`. A port forwarding on the local interface 127.0.0.1 from port 8888 to the container port 8888 |
6868
| quay.io/jupyter/minimal-notebook:2025-06-23 | The image to create the container from |
6969

70+
> <comment-title>Docker CLI</comment-title>
71+
> The complete docker cli reference can be found at [https://docs.docker.com/reference/cli/docker/](https://docs.docker.com/reference/cli/docker/)
72+
{: .comment}
73+
7074
## Access your local Notebook Server
7175

7276
The above command will print out a link to `http://localhost:8888/lab?token=<token>`. Copy this link into your browser or just right-click-open the link. You will then see your JupyterLab loading.
@@ -101,28 +105,58 @@ As you will see, this fails with a `ModuleNotFoundError` as cowsay is not availa
101105

102106
# Build your first custom Image
103107

104-
In order to customize this Container Image, we need a so-called `Dockerfile`. Go ahead, create a new directory as your playground. Then, create a file called `Dockerfile` in this new directory.
108+
Of course, you could run `pip install cowsay` in order to have the package available in your notebook. For a simple package installation like this, adding an install step inside the Notebook document itself might be feasible. But in general the installation of tooling should be done on beforehand. Not only is it more convinient, it also is also helps reproducing.
105109

106-
Fill it with content:
110+
So we'll add the `cowsay` package as a simple example for customization. In order to customize the `minimal-notebook` Container Image, we need a so-called `Dockerfile`.
107111

108-
```dockerfile
109-
# First, we say from which container image we want to start
110-
# This is called the base image
111-
FROM quay.io/jupyter/minimal-notebook:2025-06-23
112+
> <hands-on-title></hands-on-title>
113+
>
114+
> Create a new directory as your playground. Then, create a file called `Dockerfile` in this new directory.
115+
>
116+
> Fill the Dockerfile with this content:
117+
>
118+
> ```dockerfile
119+
> # First, we say from which container image we want to start
120+
> # This is called the base image
121+
> FROM quay.io/jupyter/minimal-notebook:2025-06-23
122+
>
123+
> # Now, we can run arbitrary commands in order to extend the base image
124+
> RUN pip install --no-cache-dir cowsay
125+
> ```
126+
{: .hands_on}
112127
113-
# Now, we can run arbitrary commands in order to extend the base image
114-
RUN pip install --quiet --no-cache-dir cowsay
115-
```
128+
> <comment-title>Let's tear this command apart</comment-title>
129+
>
130+
> |---|---|
131+
> | FROM | This tells docker from which image to start building |
132+
> | RUN | Runs an arbitrary command on top of the image and thus creates a new image layer |
133+
{: .comment}
116134
117-
* Build it, mind the period at the end of the command
135+
> <comment-title>Let's tear this command apart</comment-title>
136+
>
137+
> The complete Dockerfile reference can be found at [https://docs.docker.com/reference/dockerfile/](https://docs.docker.com/reference/dockerfile/).
138+
{: .comment}
139+
140+
> <hands-on-title></hands-on-title>
141+
>
142+
> In order to build the customized image, run the following command. Please mind the period dot at the end of the command.
143+
>
144+
> ```bash
145+
> sudo docker build -t my-custom-jupyterlab .
146+
> ```
147+
{: .hands_on}
148+
149+
> <comment-title>docker build</comment-title>
150+
>
151+
> The `-t` option tells docker to tag the built image with provided tag (`my-custom-jupyterlab`). The `docker build` command needs a build context as the last parameter. We tell docker to use the current directory (`.`) as build context.
152+
{: .comment}
118153
119-
```bash
120-
sudo docker build -t my-custom-jupyterlab .
121-
```
122154
123155
124156
# Use your first custom Image
125157
158+
You may use the newly build image just the same way you have used the `minimal-notebook` image beforehand, just use the tag you have provided with your build command:
159+
126160
```bash
127161
sudo docker run --rm -p 127.0.0.1:8888:8888 my-custom-jupyterlab
128162
```
@@ -132,23 +166,28 @@ Again, you'll provided with a link to open you jupyterlab. Start a Pyhton 3 Note
132166
Again, run:
133167

134168
```python
169+
# Hint: press shift + enter to execute code in Jupyter Notebook
170+
import datetime
135171
from cowsay import cow
136-
cow('Muuuuh')
137-
```
138-
139-
As you will see, the command now succeeds and prints a nice graphical text output.
140172

141-
# Exercise: build your own custom Image
173+
now = datetime.datetime.now()
174+
cow(now.strftime("%A"))
175+
```
142176

143-
Now, let's go ahead and try out some real usecase.
177+
As you will see, the command now succeeds and prints a ascii-cow with the current weekday.
144178

145-
> Create a custom notebook from the `scipy-notebook` base image and install the `igv-browser` extension.
179+
# Build your own customized JupyterLab
146180

147-
You succeeded, if you can run following snippet successfully and are provided with a genome browser with loaded track:
181+
You now know how to make basic customizations to your JupyterLab. Let's go ahead and try out some real usecase:
148182

149183
> <hands-on-title>Make this script succeed in your custom JupyterLab</hands-on-title>
150-
>
151-
>
184+
>
185+
> Create a custom notebook from the `scipy-notebook` base image and install the `igv-browser` extension.
186+
>
187+
> You find all relevant information about this extension at [https://github.com/igvteam/igv-notebook](https://github.com/igvteam/igv-notebook).
188+
>
189+
> You have succeeded, if you can run following snippet in your JupyterLab and are provided with a genome browser with loaded track:
190+
>
152191
> ```python
153192
> # This example snippet is taken from https://github.com/igvteam/igv-notebook/blob/v3.1.4/README.md
154193
> # License: MIT License
@@ -177,54 +216,75 @@ You succeeded, if you can run following snippet successfully and are provided wi
177216
> }
178217
> )
179218
> ```
180-
{: .question}
219+
{: .hands_on}
181220
182-
> <solution-title>Proposed approach</solution-title>
221+
> <solution-title>Possible solution</solution-title>
183222
>
184-
> Keep in mind, there are many ways to solve this exercise. This proposed one is only one way to get the job done.
223+
> Keep in mind, there are many ways to solve this exercise. The proposed solution is only one way to succeed.
185224
>
186225
> 1. Create a new `Dockerfile`:
187226
> ```dockerfile
188227
> FROM quay.io/jupyter/scipy-notebook:2025-06-23
189-
> RUN pip install --quiet --no-cache-dir igv-notebook
228+
> RUN pip install --no-cache-dir igv-notebook
190229
> ```
191230
> 2. Build the new Container Image:
192231
> ```bash
193-
> sudo docker build -t my-custom-jupyterlab .
232+
> sudo docker build -t my-igv-jupyterlab .
194233
> ```
195234
> 3. Run a container from your image
196235
> ```bash
197-
> sudo docker run --rm -p 127.0.0.1:8888:8888 my-custom-jupyterlab
236+
> sudo docker run --rm -p 127.0.0.1:8888:8888 my-igv-jupyterlab
198237
> ```
199238
> 4. Access the JupyterLab via URL provided by the container output
200-
> 5. Open a Python 3 Jupyter Notebook, paste in the above code and run it. It should work now.
239+
> 5. Open a Python 3 Jupyter Notebook, paste in the above snippet and run it
240+
> 6. You should be provided with a genome browser with loaded track
201241
{: .solution}
202242
203243
# Docker Compose
204244
205-
While running all these docker commands into the command line directly works fine, it has significant disadvantages: it's verbose and therefore error-prone, it's difficult to reproduce and it's difficult to share and version.
245+
Even though running all these docker commands directly from the command line works fine, it has significant disadvantages:
246+
- it's verbose and therefore error-prone
247+
- it's difficult to reproduce
248+
- it's difficult to share and version
206249
207-
A better approach is to use a `docker-compose` setup. All relevant config is written into a file called `compose.yml`, which is sharable, reproducable and versionizable.
208-
209-
```yaml
210-
services:
211-
jupyterlab:
212-
image: my-custom-jupyterlab
213-
build:
214-
context: .
215-
dockerfile: Dockerfile
216-
ports:
217-
- 127.0.0.1:8888:8888
218-
```
250+
A better approach is to use a container composition, e.g. with dockers `compose` plugin. All relevant config is written into a file called `compose.yml`, which is reviewable, sharable, reproducable and versionizable.
219251
220-
You may now build the image simply by executing:
252+
> <hands-on-title></hands-on-title>
253+
>
254+
> Create a file called `compose.yml` inside the directory created above.
255+
>
256+
> Fill the compose file with following content:
257+
>
258+
> ```yaml
259+
> services:
260+
> jupyterlab:
261+
> image: my-custom-jupyterlab
262+
> build:
263+
> context: .
264+
> dockerfile: Dockerfile
265+
> ports:
266+
> - 127.0.0.1:8888:8888
267+
> ```
268+
{: .hands_on}
221269
222-
```
223-
sudo docker compose build
224-
```
270+
> <comment-title>Docker Compose</comment-title>
271+
>
272+
> A complete reference to the compose format can be found at [https://docs.docker.com/reference/compose-file/](https://docs.docker.com/reference/compose-file/)
273+
{: .comment}
225274
226-
An you may run it easily by executing:
275+
> <hands-on-title></hands-on-title>
276+
>
277+
> Now, build the image by simply executing:
278+
>
279+
> ```
280+
> sudo docker compose build
281+
> ```
282+
>
283+
> An then run it by simply executing:
284+
>
285+
> ```
286+
> sudo docker compose up
287+
> ```
288+
{: .hands_on}
227289
228-
```
229-
sudo docker compose up
230-
```
290+
Using a container composition is the preferred way of using containers on your local machine. However, following tutorials will guide you without compose files. Feel free to practise composition and solve the exercises using container compositions.

0 commit comments

Comments
 (0)