Skip to content

Commit

Permalink
Improved handling of environment variables for NB_USER in docker.
Browse files Browse the repository at this point in the history
  • Loading branch information
janpfeifer committed Oct 16, 2024
1 parent e36d29d commit 512462e
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 19 deletions.
17 changes: 13 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,21 @@ RUN echo "%apt-users ALL=(ALL) NOPASSWD: /usr/bin/apt update, /usr/bin/apt insta
#######################################################################################################
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 Down
9 changes: 2 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,8 @@ docker run -it --rm -p 8888:8888 -v "${PWD}":/notebooks janpfeifer/gonb_jupyterl

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

#### Docker Customized Initialization

If the container you run `gonb` needs some custom initialization, and you don't want to simply edit the dockerfile and
create your own docker, just create a files `autostart.sh` in the directory mounted under `/notebooks` in the container,
owned by `root` and with executable permissions, and it will be executed at start up of the container by default.

This allows you to download/install databases, or set up credentials, etc.
**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
14 changes: 6 additions & 8 deletions cmd/check_and_run_autostart.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@
# 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
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"
Expand All @@ -21,10 +24,5 @@ else
echo "No autostart.sh initialization script."
fi


echo "Current directory:"
pwd

# Switch to the $NB_USER, preserving environment variables.
# Notice $PATH gets rewritten anyway, so we need to explicitly set it again with the new user.
su --preserve-environment $NB_USER -c "export PATH=${PATH} ; jupyter lab"
# Run JupyterLab from $NOTEBOOKS as user $NB_USER.
su -l "${NB_USER}" -c "cd \"${NOTEBOOKS}\" ; jupyter lab"
33 changes: 33 additions & 0 deletions docs/docker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Docker Customization

If the container you run `gonb` needs some custom initialization, and you don't want to simply edit the dockerfile and
create your own docker, just create the file `autostart.sh` in the directory mounted under `/notebooks` in the container,
owned by `root` and with executable permissions, and it will be executed at start up of the container by default.

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`.

0 comments on commit 512462e

Please sign in to comment.