Skip to content
This repository was archived by the owner on Nov 30, 2023. It is now read-only.

Add JupyterLab as a feature #1335

Merged
merged 12 commits into from
Mar 14, 2022
5 changes: 3 additions & 2 deletions containers/codespaces-linux/.devcontainer/base.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ ENV SHELL=/bin/bash \
CARGO_HOME="/usr/local/cargo" \
RUSTUP_HOME="/usr/local/rustup" \
SDKMAN_DIR="/usr/local/sdkman" \
JUPYTERLAB_PATH="${HOMEDIR}/.local/bin" \
DOCKER_BUILDKIT=1

ENV PATH="${NVM_DIR}/current/bin:${NPM_GLOBAL}/bin:${ORIGINAL_PATH}:${DOTNET_ROOT}:${DOTNET_ROOT}/tools:${SDKMAN_DIR}/bin:${SDKMAN_DIR}/candidates/gradle/current/bin:${SDKMAN_DIR}/candidates/java/current/bin:/opt/maven/lts:${CARGO_HOME}/bin:${GOROOT}/bin:${GOPATH}/bin:${PIPX_BIN_DIR}:/opt/conda/condabin:${JAVA_ROOT}/current/bin:${NODE_ROOT}/current/bin:${PHP_ROOT}/current/bin:${PYTHON_ROOT}/current/bin:${RUBY_ROOT}/current/bin:${MAVEN_ROOT}/current/bin:${HUGO_ROOT}/current/bin:${ORYX_PATHS}"
ENV PATH="${NVM_DIR}/current/bin:${NPM_GLOBAL}/bin:${ORIGINAL_PATH}:${DOTNET_ROOT}:${DOTNET_ROOT}/tools:${SDKMAN_DIR}/bin:${SDKMAN_DIR}/candidates/gradle/current/bin:${SDKMAN_DIR}/candidates/java/current/bin:/opt/maven/lts:${CARGO_HOME}/bin:${GOROOT}/bin:${GOPATH}/bin:${PIPX_BIN_DIR}:/opt/conda/condabin:${JAVA_ROOT}/current/bin:${NODE_ROOT}/current/bin:${PHP_ROOT}/current/bin:${PYTHON_ROOT}/current/bin:${RUBY_ROOT}/current/bin:${MAVEN_ROOT}/current/bin:${HUGO_ROOT}/current/bin:${JUPYTERLAB_PATH}:${ORYX_PATHS}"

# Install needed utilities and setup non-root user. Use a separate RUN statement to add your own dependencies.
COPY library-scripts/* setup-user.sh first-run-notice.txt /tmp/scripts/
Expand Down Expand Up @@ -72,12 +73,12 @@ RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \

# Install Python, PHP, Ruby utilities, and JupyterLab
RUN bash /tmp/scripts/python-debian.sh "none" "/opt/python/latest" "${PIPX_HOME}" "${USERNAME}" "true" \
&& bash /tmp/scripts/jupyterlab-debian.sh \
# Install rvm, rbenv, any missing base gems
&& chown -R ${USERNAME} /opt/ruby/* \
&& bash /tmp/scripts/ruby-debian.sh "none" "${USERNAME}" "true" "true" \
# Link composer
&& ln -s $(which composer.phar) /usr/local/bin/composer \
&& pip install jupyterlab \
&& apt-get clean -y

# Install PowerShell
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/usr/bin/env bash
#-------------------------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------
#
# Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/jupyterlab.md
# Maintainer: The VS Code and Codespaces Teams
#
# Syntax: ./jupyter-debian.sh

set -e

VERSION=${1:-"latest"}
USERNAME=${2:-"automatic"}

# If in automatic mode, determine if a user already exists, if not use vscode
if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then
USERNAME=""
POSSIBLE_USERS=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)")
for CURRENT_USER in ${POSSIBLE_USERS[@]}; do
if id -u ${CURRENT_USER} > /dev/null 2>&1; then
USERNAME=${CURRENT_USER}
break
fi
done
if [ "${USERNAME}" = "" ]; then
USERNAME=vscode
fi
elif [ "${USERNAME}" = "none" ]; then
USERNAME=root
USER_UID=0
USER_GID=0
fi

# Use sudo to run as non-root user is not already running
sudoUserIf()
{
if [ "$(id -u)" -eq 0 ] && [ "${USERNAME}" != "root" ]; then
sudo -u ${USERNAME} "$@"
else
"$@"
fi
}

# If we don't yet have Python, install it now.
if ! python --version > /dev/null ; then
echo "You need to install Python before installing JupyterLab."
exit 1
fi

# If we don't already have JupyterLab installed, install it now.
if ! jupyter-lab --version > /dev/null ; then
echo "Installing JupyterLab..."
if [ "${VERSION}" = "latest" ]; then
sudoUserIf pip install jupyterlab
else
sudoUserIf pip install jupyterlab=="${VERSION}" --no-cache-dir
fi
fi
2 changes: 1 addition & 1 deletion containers/python-3-anaconda/.devcontainer/base.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ FROM mcr.microsoft.com/vscode/devcontainers/base:0-bullseye
COPY --from=upstream /opt /opt/

# Copy library scripts to execute
COPY .devcontainer/library-scripts/node-debian.sh .devcontainer/add-notice.sh .devcontainer/library-scripts/*.env /tmp/library-scripts/
COPY .devcontainer/library-scripts/*.sh .devcontainer/add-notice.sh .devcontainer/library-scripts/*.env /tmp/library-scripts/

# Setup conda to mirror contents from https://github.com/ContinuumIO/docker-images/blob/master/anaconda3/debian/Dockerfile
ENV LANG=C.UTF-8 \
Expand Down
1 change: 1 addition & 0 deletions script-library/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Some scripts have special installation instructions (like `desktop-lite-debian.s
| [Gradle Install Script](docs/gradle.md) | `gradle-debian.sh` | VS Code and GitHub Codespaces teams|
| [Homebrew Install Script](docs/homebrew.md) | `homebrew-debian.sh` (Community) | [@andreiborisov](https://github.com/andreiborisov) |
| [Java Install Script](docs/java.md) | `java-debian.sh` | VS Code and GitHub Codespaces teams|
| [JupyterLab Install Script](docs/jupyterlab.md) | `jupyterlab-debian.sh` | VS Code and GitHub Codespaces teams|
| [Kubectl and Helm Install Script](docs/kubectl-helm.md) | `kubectl-helm-debian.sh` | VS Code and GitHub Codespaces teams|
| [Maven Install Script](docs/maven.md) | `maven-debian.sh` | VS Code and GitHub Codespaces teams|
| [Node.js Install Script](docs/node.md) | `node-debian.sh` | VS Code and GitHub Codespaces teams|
Expand Down
27 changes: 27 additions & 0 deletions script-library/container-features/src/devcontainer-features.json
Original file line number Diff line number Diff line change
Expand Up @@ -1170,6 +1170,33 @@
"ruby-rails-postgres",
"python-3-postgres"
]
},
{
"id": "jupyterlab",
"name": "Jupyter Lab",
"documentationURL": "https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/jupyterlab.md",
"options": {
"version": {
"type": "string",
"proposals": ["latest", "3.6.2"],
"default": "latest",
"description": "Select or enter a jupyterlab version."
}
},
"buildArg": "_VSC_INSTALL_JUPYTERLAB",
"extensions": [
"ms-python.python",
"ms-python.vscode-pylance",
"ms-toolsai.jupyter"
],
"include": [
"codespaces-linux",
"python-3",
"python-3-anaconda",
"python-3-miniconda",
"ubuntu",
"debian"
]
}
]
}
1 change: 1 addition & 0 deletions script-library/container-features/src/feature-scripts.env
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ _VSC_INSTALL_RUST="rust-debian.sh /usr/local/cargo /usr/local/rustup automatic t
_VSC_INSTALL_POWERSHELL="powershell-debian.sh ${_BUILD_ARG_POWERSHELL_VERSION:-latest}"
_VSC_INSTALL_DESKTOP_LITE="desktop-lite-debian.sh automatic ${_BUILD_ARG_DESKTOP_LITE_PASSWORD:-vscode} true ${_BUILD_ARG_DESKTOP_LITE_VNCPORT:-5901} ${_BUILD_ARG_DESKTOP_LITE_WEBPORT:-6080}"
_VSC_INSTALL_DOTNET="dotnet-debian.sh ${_BUILD_ARG_DOTNET_VERSION:-latest} ${_BUILD_ARG_DOTNET_RUNTIMEONLY:-false} automatic true /usr/local/dotnet dotnet"
_VSC_INSTALL_JUPYTERLAB="jupyterlab-debian.sh ${_BUILD_ARG_JUPYTERLAB_VERSION:-latest}"
57 changes: 57 additions & 0 deletions script-library/docs/jupyterlab.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# JupyterLab Install Script

*Installs JupyterLab.*

**Script status**: Stable

**OS support**: Debian 9+, Ubuntu 18.04+, and downstream distros.

**Maintainer**: GitHub Codespaces team

## Syntax

```text
./jupyterlab-debian.sh
```

Or as a feature:

```json
"features": {
"jupyterlab": {
"version": "latest"
}
}
```

## Usage

### Feature use

To install this feature in your primary dev container, reference it in `devcontainer.json` as follows:

```json
"features": {
"jupyterlab": {
"version": "latest"
}
}
```

If you have already built your development container, run the **Rebuild Container** command from the command
palette (<kdb>Ctrl/Cmd</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd> or <kbd>F1</kbd>) to pick up the change.

You must have Python already installed in order to use this feature.

### Script use

1. Add [`jupyterlab-debian.sh`](../jupyterlab-debian.sh) to `.devcontainer/library-scripts`

2. Add the following to your `.devcontainer/Dockerfile`:

```Dockerfile
COPY library-scripts/jupyterlab-debian.sh /tmp/library-scripts/
RUN bash /tmp/library-scripts/jupyterlab-debian.sh
```

That's it!
60 changes: 60 additions & 0 deletions script-library/jupyterlab-debian.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/usr/bin/env bash
#-------------------------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------
#
# Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/jupyterlab.md
# Maintainer: The VS Code and Codespaces Teams
#
# Syntax: ./jupyter-debian.sh

set -e

VERSION=${1:-"latest"}
USERNAME=${2:-"automatic"}

# If in automatic mode, determine if a user already exists, if not use vscode
if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then
USERNAME=""
POSSIBLE_USERS=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)")
for CURRENT_USER in ${POSSIBLE_USERS[@]}; do
if id -u ${CURRENT_USER} > /dev/null 2>&1; then
USERNAME=${CURRENT_USER}
break
fi
done
if [ "${USERNAME}" = "" ]; then
USERNAME=vscode
fi
elif [ "${USERNAME}" = "none" ]; then
USERNAME=root
USER_UID=0
USER_GID=0
fi

# Use sudo to run as non-root user is not already running
sudoUserIf()
{
if [ "$(id -u)" -eq 0 ] && [ "${USERNAME}" != "root" ]; then
sudo -u ${USERNAME} "$@"
else
"$@"
fi
}

# If we don't yet have Python, install it now.
if ! python --version > /dev/null ; then
echo "You need to install Python before installing JupyterLab."
exit 1
fi

# If we don't already have JupyterLab installed, install it now.
if ! jupyter-lab --version > /dev/null ; then
echo "Installing JupyterLab..."
if [ "${VERSION}" = "latest" ]; then
sudoUserIf pip install jupyterlab
else
sudoUserIf pip install jupyterlab=="${VERSION}" --no-cache-dir
fi
fi