Skip to content

Commit bed2f86

Browse files
authored
Merge pull request #140 from janpfeifer/docker
Docker customization
2 parents 78b21ef + 427c299 commit bed2f86

File tree

6 files changed

+130
-29
lines changed

6 files changed

+130
-29
lines changed

Dockerfile

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,26 +16,44 @@
1616
#######################################################################################################
1717
# Base image from JupyterLab
1818
#######################################################################################################
19-
ARG BASE_IMAGE=jupyter/base-notebook
19+
ARG BASE_IMAGE=quay.io/jupyter/base-notebook
2020
ARG BASE_TAG=latest
2121
FROM ${BASE_IMAGE}:${BASE_TAG}
2222

23-
# Update apt and install basic utils
23+
# Update apt and install basic utils that may be helpful for users to install their own dependencies.
2424
USER root
2525
RUN apt update --yes
26-
RUN apt install --yes --no-install-recommends wget git
26+
RUN apt install --yes --no-install-recommends \
27+
sudo wget git openssh-client rsync curl
28+
29+
# Give NB_USER sudo power for "/usr/bin/apt-get install/update" or "/usr/bin/apt install/update".
30+
USER root
31+
RUN groupadd apt-users
32+
RUN usermod -aG apt-users $NB_USER
33+
# Allow members of the apt-users group to execute only apt-get commands without a password
34+
RUN echo "%apt-users ALL=(ALL) NOPASSWD: /usr/bin/apt-get update, /usr/bin/apt-get install *" >> /etc/sudoers
35+
RUN echo "%apt-users ALL=(ALL) NOPASSWD: /usr/bin/apt update, /usr/bin/apt install *" >> /etc/sudoers
2736

2837
#######################################################################################################
2938
# Go and GoNB Libraries
3039
#######################################################################################################
3140
ARG GO_VERSION=1.23.2
3241
ENV GOROOT=/usr/local/go
33-
ENV GOPATH=/opt/go
42+
ENV GOPATH=$HOME/go
3443
ENV PATH=$PATH:$GOROOT/bin:$GOPATH/bin
3544

36-
# Create Go directory for user -- that will not move if the user home directory is moved.
37-
USER root
38-
RUN mkdir ${GOPATH} && chown ${NB_USER}:users ${GOPATH}
45+
# Add exported variables to $NB_USER .profile: notice we start the docker as root, and it executes
46+
# JupyterLab with a `su -l $NB_USER`, so the environment variables are lost. We could use --preserve_environment
47+
# for GOROOT and GOPATH, but it feels safer to add these to .profile, so the autostart.sh script can also
48+
# execute `su -l $NB_USER -c "<some command>"` if it wants.
49+
USER $NB_USER
50+
WORKDIR ${HOME}
51+
RUN <<EOF
52+
echo "NB_USER=${NB_USER}" >> .profile
53+
echo "export PATH=${PATH}" >> .profile
54+
echo "export GOPATH=${GOPATH}" >> .profile
55+
echo "export GOROOT=${GOROOT}" >> .profile
56+
EOF
3957

4058
USER root
4159
WORKDIR /usr/local
@@ -56,7 +74,7 @@ RUN export GOPROXY=direct && \
5674
# Prepare directory where Jupyter Lab will run, with the notebooks we want to demo
5775
####################################################################################################### \
5876
USER root
59-
ARG NOTEBOOKS=/notebooks
77+
ENV NOTEBOOKS=/notebooks
6078

6179
# Create directory where notebooks will be stored, where Jupyter Lab will run by default.
6280
RUN mkdir ${NOTEBOOKS} && chown ${NB_USER}:users ${NOTEBOOKS}
@@ -77,8 +95,11 @@ USER root
7795
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
7896

7997
# Start-up.
80-
USER $NB_USER
98+
USER root
8199
WORKDIR ${NOTEBOOKS}
82100

83-
EXPOSE 8888
84-
ENTRYPOINT ["tini", "-g", "--", "jupyter", "lab"]
101+
# Script that checks for `autostart.sh` (and runs it if owned by root and present), and then starts
102+
# JupyterLab.
103+
COPY cmd/check_and_run_autostart.sh /usr/local/bin/
104+
105+
ENTRYPOINT ["tini", "-g", "--", "/usr/local/bin/check_and_run_autostart.sh"]

README.md

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# GoNB, A Modern Go Kernel for Jupyter Notebooks
1+
# GoNB, A Modern Go Kernel for Jupyter 📓Notebooks📓
22

33
[![GoDev](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white)](https://pkg.go.dev/github.com/janpfeifer/gonb?tab=doc)
44
[![GitHub](https://img.shields.io/github/license/janpfeifer/gonb)](https://github.com/Kwynto/gosession/blob/master/LICENSE)
@@ -9,15 +9,12 @@
99

1010

1111

12-
## For a quick start, see the [**tutorial**](examples/tutorial.ipynb)!
12+
## For a quick start, see the [**tutorial** 🧭](examples/tutorial.ipynb)
1313

14-
## Highlights:
14+
## Highlights:
1515

1616
<img align="right" width="480px" src="https://repository-images.githubusercontent.com/599714179/38d0328a-abdb-4f69-9617-6ef136390708">
1717

18-
* **NEW**: Now supported by [Jupytext](https://github.com/mwouts/jupytext): it allows one to write the notebook as a normal.
19-
Go file, and use [Jupytext](https://github.com/mwouts/jupytext) to convert to a notebook (with markdown support, etc).
20-
See [example](https://github.com/mwouts/jupytext/issues/1244#issuecomment-2202097837).
2118
* Auto-complete and contextual help while coding.
2219
* Rich content display: HTML, markdown (with latex), images, javascript, svg, videos, etc.
2320
* Widgets (sliders, buttons) support: interact using HTML elements. Create your own widgets!
@@ -27,6 +24,9 @@
2724
It also supports arbitrary Go compilation flags to be used when executing the cells.
2825
* Faster execution than interpreted Go, used in other similar kernels -- at the cost of imperceptible increased
2926
start up, since each cell is compiled.
27+
* Supported by [Jupytext](https://github.com/mwouts/jupytext): it allows one to write the notebook as a normal.
28+
Go file, and use [Jupytext](https://github.com/mwouts/jupytext) to convert to a notebook (with markdown support, etc).
29+
See [example](https://github.com/mwouts/jupytext/issues/1244#issuecomment-2202097837).
3030
* Run cell's `Test*` and `Benchmark*` functions with `go test`, simply adding `%test` to cell.
3131
* Support for `go.mod` and `go.work`, to allow local development. Including importing specific versions of libraries.
3232
* Debug using [gdlv](https://github.com/aarzilli/gdlv), a GUI for the [delve](https://github.com/go-delve/delve) debugger (see %help).
@@ -38,7 +38,7 @@
3838
* Online help and much more, see `%help`.
3939
* Compile and execute the Go code as WASM: allows one to do interactive widgets in notebooks. See `%wasm` (EXPERIMENTAL).
4040

41-
## Examples:
41+
## 👁️‍🗨️ Examples:
4242

4343
### Auto-complete and Contextual Help
4444

@@ -57,7 +57,7 @@ https://github.com/janpfeifer/gonb/assets/7460115/f1187dad-4c10-4d21-a73e-909001
5757

5858
<img src="docs/demo-browser.png" alt="Browser Screenshot Demo" width="50%" height="50%"/>
5959

60-
## Introduction
60+
## 🌱 Introduction
6161

6262
Go is a compiled language, but with very fast compilation, that allows one to use
6363
it in a REPL (Read-Eval-Print-Loop) fashion, by inserting a "Compile" step in the middle
@@ -84,15 +84,15 @@ There is also
8484
that one can interact with (make a copy first) — if the link doesn't work (Google Drive sharing publicly
8585
is odd), [download it from GitHub](examples/google_colab_demo.ipynb) and upload it to Google's Colab.
8686

87-
Finally, because it's compiled and not intepreted, it has a slightly different "semantic" than the Python kernels.
87+
Finally, because it's compiled and not interpreted, it has a slightly different "semantic" than the Python kernels.
8888
It's highly recommended quickly browsing through the [**tutorial**](examples/tutorial.ipynb).
8989

90-
## Installation
90+
## 📦 Installation
9191

9292
**Only for Linux and macOS. In Windows, it works in WSL or inside a Docker**
9393

9494

95-
### Docker
95+
### 🐳 Docker
9696

9797
GoNB offers a [pre-built docker](https://hub.docker.com/r/janpfeifer/gonb_jupyterlab),
9898
that includes JupyterLab and GoNB.
@@ -104,11 +104,13 @@ To start it:
104104

105105
```shell
106106
docker pull janpfeifer/gonb_jupyterlab:latest
107-
docker run -it --rm -p 8888:8888 -v "${PWD}":/notebooks/host janpfeifer/gonb_jupyterlab:latest
107+
docker run -it --rm -p 8888:8888 -v "${PWD}":/notebooks janpfeifer/gonb_jupyterlab:latest
108108
```
109109

110110
Then copy&paste the URL that it outputs in your browser.
111111

112+
**Note**: The docker allows for customization by running an arbitrary script at start up as `root`, which allows
113+
one to install any planned dependencies. See [docker.md](docs/docker.md) for details.
112114

113115
### Linux and macOS Installation Using Standard Go Tools
114116

@@ -149,7 +151,7 @@ Install there as if it were in a linux machine.
149151

150152
A pure Windows installation is not supported at this time — but contributions to add support for it would be welcome :)
151153

152-
## FAQ
154+
## 🤔 FAQ
153155

154156
* Is there are reference documentation ?
155157
* There is a help (run `%help` in a cell) and a [**tutorial**](examples/tutorial.ipynb), which is kept up-to-date and
@@ -163,15 +165,15 @@ A pure Windows installation is not supported at this time — but contributions
163165
solutions to this. Often folks create a series of `Must()` functions, or simply use
164166
[this trivial `must` package](https://github.com/janpfeifer/must).
165167

166-
## TODOs
168+
## 📝 TODOs
167169

168170
Contributions are welcome!
169171

170172
* Windows version:
171173
* Installation.
172174
* Named-pipe implementation in `kernel/pipeexec.go`.
173175

174-
## Thanks
176+
## 💖 Thanks
175177

176178
* [Go](golang.org)
177179
* [Jupyter](https://jupyter.org/), what an awesome project.
@@ -180,7 +182,7 @@ Contributions are welcome!
180182
(http://reneefrench.blogspot.com/), see Creative Commons 3.0 Attributions license in
181183
[Wikimedia](https://commons.wikimedia.org/wiki/File:Go_gopher_favicon.svg).
182184

183-
## Contributing
185+
## 🤝 Contributing
184186

185187
Contributions are very welcome. The code is generally well documented -- not always, but mostly. There are a also a couple of guides worth reading if contributing in the [`docs/`](https://github.com/janpfeifer/gonb/tree/main/docs) subdirectory.
186188

@@ -189,6 +191,6 @@ There are two parts of the project:
189191
1. The kernel itself: that builds the binary package. Most subpackages are under `internal/`.
190192
2. The UI library in the packages under `github.com/janpfeifer/gonb/gonbui`.
191193

192-
## Star History
194+
## 🌟 Star History
193195

194196
[![Star History Chart](https://api.star-history.com/svg?repos=janpfeifer/gonb&type=Date)](https://star-history.com/#janpfeifer/gonb&Date)

binder/postBuild

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/bin/bash
22
set -eu
33

4-
GO_VERSION=1.20
4+
GO_VERSION=1.23.2
55

66
curl -sfL https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz | tar -xz
77

cmd/check_and_run_autostart.sh

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/bin/bash
2+
3+
# This script is included in the Docker, and is executed at startup of the docker, allowing the user to write
4+
# an arbitrary setup script in `autostart.sh` for the image -- things like installing databases, credentials, etc.
5+
#
6+
# Notice ${NOTEBOOKS} is /notebooks in the container, and is assumed to be mounted from the host directory that
7+
# will have the users notebooks.
8+
9+
# Makes sure we are not using $NB_USER's GOPATH.
10+
export GOPATH=/root/go
11+
12+
# Check if autostart.sh exists
13+
if [[ -f "${NOTEBOOKS}/autostart.sh" ]]; then
14+
# Check if it's owned by root and is executable
15+
if [[ "$(stat -c '%U' "${NOTEBOOKS}/autostart.sh")" = "root" && -x "${NOTEBOOKS}/autostart.sh" ]]; then
16+
# Run autostart.sh as root
17+
echo "Running autostart.sh as root..."
18+
"${NOTEBOOKS}/autostart.sh"
19+
else
20+
# Print a message indicating why it's not running
21+
echo "autostart.sh exists but is not owned by root or not executable. Not running it."
22+
fi
23+
else
24+
echo "No autostart.sh initialization script."
25+
fi
26+
27+
# Run JupyterLab from $NOTEBOOKS as user $NB_USER.
28+
su -l "${NB_USER}" -c "cd \"${NOTEBOOKS}\" ; jupyter lab"

docs/CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# GoNB Changelog
22

3+
## Next
4+
5+
* Feature request #138
6+
* Added openssh-client, rsync and curl, to allow users to install other dependencies.
7+
* Added sudo for apt install and apt update.
8+
* Added support for `autostart.sh` that if present in the mounted container `/notebooks` directory, and if root owned
9+
and set as executable.
10+
* Updated Dockerfile to latest version to JupyterLab -- now the base docker is served `quay.io/jupyter/base-notebook`
11+
312
## v0.10.5, Added SendAsDownload
413

514
* Added `dom.SendAsDownload` to send data from cells to the client by triggering a browser download. #134

docs/docker.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Docker Customization
2+
3+
1. The docker runs _JupyterLab_ and _GoNB_ under the user `$NB_USER` (== "jovyan").
4+
2. It has configured `sudo` privileges for `apt update` and `apt install *`. So a cell with
5+
`!sudo apt install <my_package>` will work, and install your package.
6+
3. One can always create another docker based on `janpfeifer/gonb_jupyterlab@latest`
7+
4. Create an `autostart.sh` script, see next section.
8+
9+
## Customization with `autostart.sh`
10+
11+
If you create the file `autostart.sh` in the directory mounted under `/notebooks` in the container,
12+
**owned by `root` and with executable permissions**, it will be executed at start up of the container by default
13+
**as `root`**.
14+
15+
This allows you to download/install databases, or set up credentials, etc.
16+
17+
Example of an `autostart.sh` that:
18+
19+
- Sets the timezone
20+
- Installs [`nats`](github.com/nats-io/natscli/) for the jupyer user (given by `$NB_USER`).
21+
22+
```
23+
# Set the German timezone (so time.Now() returns German time)
24+
apt-get install -y tzdata
25+
ln -sf /usr/share/zoneinfo/Europe/Berlin /etc/localtime
26+
27+
# some locale magic to make "date" answer with German format
28+
echo 'de_DE.UTF-8 UTF-8' >> /etc/locale.gen
29+
locale-gen
30+
echo 'LC_ALL="de_DE.utf8"' > /etc/default/locale
31+
export LC_ALL="de_DE.UTF-8"
32+
dpkg-reconfigure locales
33+
34+
# check that it works
35+
date
36+
37+
# Installing Go tools for $NB_USER.
38+
su -l "$NB_USER" -c "go install github.com/nats-io/natscli/nats@latest"
39+
```
40+
41+
More details in the `Dockerfile` and in the small start script `cmd/check_and_run_autostart.sh`.

0 commit comments

Comments
 (0)