Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extra tools for docker #140

Merged
merged 8 commits into from
Oct 16, 2024
Merged
43 changes: 32 additions & 11 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,44 @@
#######################################################################################################
# Base image from JupyterLab
#######################################################################################################
ARG BASE_IMAGE=jupyter/base-notebook
ARG BASE_IMAGE=quay.io/jupyter/base-notebook
ARG BASE_TAG=latest
FROM ${BASE_IMAGE}:${BASE_TAG}

# Update apt and install basic utils
# Update apt and install basic utils that may be helpful for users to install their own dependencies.
USER root
RUN apt update --yes
RUN apt install --yes --no-install-recommends wget git
RUN apt install --yes --no-install-recommends \
sudo wget git openssh-client rsync curl

# Give NB_USER sudo power for "/usr/bin/apt-get install/update" or "/usr/bin/apt install/update".
USER root
RUN groupadd apt-users
RUN usermod -aG apt-users $NB_USER
# Allow members of the apt-users group to execute only apt-get commands without a password
RUN echo "%apt-users ALL=(ALL) NOPASSWD: /usr/bin/apt-get update, /usr/bin/apt-get install *" >> /etc/sudoers
RUN echo "%apt-users ALL=(ALL) NOPASSWD: /usr/bin/apt update, /usr/bin/apt install *" >> /etc/sudoers

#######################################################################################################
# Go and GoNB Libraries
#######################################################################################################
ARG GO_VERSION=1.23.2
ENV GOROOT=/usr/local/go
ENV GOPATH=/opt/go
ENV GOPATH=$HOME/go
ENV PATH=$PATH:$GOROOT/bin:$GOPATH/bin

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

USER root
WORKDIR /usr/local
Expand All @@ -56,7 +74,7 @@ RUN export GOPROXY=direct && \
# Prepare directory where Jupyter Lab will run, with the notebooks we want to demo
####################################################################################################### \
USER root
ARG NOTEBOOKS=/notebooks
ENV NOTEBOOKS=/notebooks

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

# Start-up.
USER $NB_USER
USER root
WORKDIR ${NOTEBOOKS}

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

ENTRYPOINT ["tini", "-g", "--", "/usr/local/bin/check_and_run_autostart.sh"]
36 changes: 19 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# GoNB, A Modern Go Kernel for Jupyter Notebooks
# GoNB, A Modern Go Kernel for Jupyter 📓Notebooks📓

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



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

## Highlights:
## Highlights:

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

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

## Examples:
## 👁️‍🗨️ Examples:

### Auto-complete and Contextual Help

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

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

## Introduction
## 🌱 Introduction

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

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

## Installation
## 📦 Installation

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


### Docker
### 🐳 Docker

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

```shell
docker pull janpfeifer/gonb_jupyterlab:latest
docker run -it --rm -p 8888:8888 -v "${PWD}":/notebooks/host janpfeifer/gonb_jupyterlab:latest
docker run -it --rm -p 8888:8888 -v "${PWD}":/notebooks janpfeifer/gonb_jupyterlab:latest
```

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

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

### Linux and macOS Installation Using Standard Go Tools

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

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

## FAQ
## 🤔 FAQ

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

## TODOs
## 📝 TODOs

Contributions are welcome!

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

## Thanks
## 💖 Thanks

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

## Contributing
## 🤝 Contributing

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.

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

## Star History
## 🌟 Star History

[![Star History Chart](https://api.star-history.com/svg?repos=janpfeifer/gonb&type=Date)](https://star-history.com/#janpfeifer/gonb&Date)
2 changes: 1 addition & 1 deletion binder/postBuild
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/bin/bash
set -eu

GO_VERSION=1.20
GO_VERSION=1.23.2

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

Expand Down
28 changes: 28 additions & 0 deletions cmd/check_and_run_autostart.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/bin/bash

# This script is included in the Docker, and is executed at startup of the docker, allowing the user to write
# an arbitrary setup script in `autostart.sh` for the image -- things like installing databases, credentials, etc.
#
# Notice ${NOTEBOOKS} is /notebooks in the container, and is assumed to be mounted from the host directory that
# will have the users notebooks.

# Makes sure we are not using $NB_USER's GOPATH.
export GOPATH=/root/go

# Check if autostart.sh exists
if [[ -f "${NOTEBOOKS}/autostart.sh" ]]; then
# Check if it's owned by root and is executable
if [[ "$(stat -c '%U' "${NOTEBOOKS}/autostart.sh")" = "root" && -x "${NOTEBOOKS}/autostart.sh" ]]; then
# Run autostart.sh as root
echo "Running autostart.sh as root..."
"${NOTEBOOKS}/autostart.sh"
else
# Print a message indicating why it's not running
echo "autostart.sh exists but is not owned by root or not executable. Not running it."
fi
else
echo "No autostart.sh initialization script."
fi

# Run JupyterLab from $NOTEBOOKS as user $NB_USER.
su -l "${NB_USER}" -c "cd \"${NOTEBOOKS}\" ; jupyter lab"
9 changes: 9 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# GoNB Changelog

## Next

* Feature request #138
* Added openssh-client, rsync and curl, to allow users to install other dependencies.
* Added sudo for apt install and apt update.
* Added support for `autostart.sh` that if present in the mounted container `/notebooks` directory, and if root owned
and set as executable.
* Updated Dockerfile to latest version to JupyterLab -- now the base docker is served `quay.io/jupyter/base-notebook`

## v0.10.5, Added SendAsDownload

* Added `dom.SendAsDownload` to send data from cells to the client by triggering a browser download. #134
Expand Down
41 changes: 41 additions & 0 deletions docs/docker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Docker Customization

1. The docker runs _JupyterLab_ and _GoNB_ under the user `$NB_USER` (== "jovyan").
2. It has configured `sudo` privileges for `apt update` and `apt install *`. So a cell with
`!sudo apt install <my_package>` will work, and install your package.
3. One can always create another docker based on `janpfeifer/gonb_jupyterlab@latest`
4. Create an `autostart.sh` script, see next section.

## Customization with `autostart.sh`

If you create the file `autostart.sh` in the directory mounted under `/notebooks` in the container,
**owned by `root` and with executable permissions**, it will be executed at start up of the container by default
**as `root`**.

This allows you to download/install databases, or set up credentials, etc.

Example of an `autostart.sh` that:

- Sets the timezone
- Installs [`nats`](github.com/nats-io/natscli/) for the jupyer user (given by `$NB_USER`).

```
# Set the German timezone (so time.Now() returns German time)
apt-get install -y tzdata
ln -sf /usr/share/zoneinfo/Europe/Berlin /etc/localtime

# some locale magic to make "date" answer with German format
echo 'de_DE.UTF-8 UTF-8' >> /etc/locale.gen
locale-gen
echo 'LC_ALL="de_DE.utf8"' > /etc/default/locale
export LC_ALL="de_DE.UTF-8"
dpkg-reconfigure locales

# check that it works
date

# Installing Go tools for $NB_USER.
su -l "$NB_USER" -c "go install github.com/nats-io/natscli/nats@latest"
```

More details in the `Dockerfile` and in the small start script `cmd/check_and_run_autostart.sh`.
Loading