Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
df772c0
initial commits for the nemo container custom app
PeterSu92 Aug 12, 2025
5feb355
adding Dockerfile using nvcr.io/nvidia/nemo:24.09
PeterSu92 Aug 12, 2025
fc72322
putting the image directly in docker-compose.yaml
PeterSu92 Aug 13, 2025
87b5368
commented out the sudo command at the end
PeterSu92 Aug 13, 2025
afa24f7
fixed syntax error with network spacing, set user to root
PeterSu92 Aug 13, 2025
05d12e3
fixed more indentation errors
PeterSu92 Aug 14, 2025
86a9f2c
indentation fix not persisting?
PeterSu92 Aug 14, 2025
1c9fb67
removed initialize command, hardcoded /workspace as the post-startup.…
PeterSu92 Aug 15, 2025
aa564e0
added the jupyter command back in
PeterSu92 Aug 15, 2025
0ad46fb
adding files for parabricks container, only differs from nemo in the …
PeterSu92 Aug 18, 2025
daa2c4a
modifying parabricks container to run command: tail -f /dev/null
PeterSu92 Aug 18, 2025
e7e41f4
adding a workbench-jupyter-parabricks directory
PeterSu92 Aug 18, 2025
f80d11c
adding restart: always to the parabricks app
PeterSu92 Aug 20, 2025
186c642
replacing wb with /usr/bin/wb to avoid conflicts with the weights&bia…
PeterSu92 Aug 20, 2025
c13dcf9
Removing parabricks standalone
PeterSu92 Aug 20, 2025
738c16b
alias the weightsbiases in the postCreateCommand in the devcontainer …
PeterSu92 Aug 20, 2025
232f381
removing erroneous wb replacement
PeterSu92 Aug 21, 2025
13aaca6
replacing more instances of wb with /usr/bin/wb
PeterSu92 Aug 21, 2025
f7145fc
replacing more instances of wb
PeterSu92 Aug 21, 2025
460e4b2
replaced /usr/bin/wb with
PeterSu92 Aug 21, 2025
0297a9d
added mappings back into .devcontainer.json
PeterSu92 Aug 21, 2025
65f2f23
updating devcontainer-template id and description
PeterSu92 Aug 21, 2025
1451e1b
adding quotes around all calls to {WORKBENCH_INSTALL_PATH}
PeterSu92 Aug 21, 2025
345417f
updated some descriptions and IDs
PeterSu92 Aug 21, 2025
09bb4a7
using a Dockerfile that now starts from the parabricks container base…
PeterSu92 Aug 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions src/workbench-jupyter-parabricks/.devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"name": "Workbench JupyterLab with docker support devcontainer template plus NVIDIA Parabricks",
"dockerComposeFile": "docker-compose.yaml",
"service": "app",
"shutdownAction": "none",
"workspaceFolder": "/workspace",
// Get the host's docker group ID and propagate it into the .env file, which
// allows it to be used within docker-compose.yaml.
"initializeCommand": "DOCKER_GID=`getent group docker | cut -d: -f3` && echo \"DOCKER_GID=${DOCKER_GID}\" > .env",
"postCreateCommand": "./startupscript/post-startup.sh jupyter /home/jupyter ${templateOption:cloud} ${templateOption:login} && ./startupscript/setup-docker.sh",
// re-mount bucket files on container start up
"postStartCommand": [
"./startupscript/remount-on-restart.sh",
"jupyter",
"/home/jupyter",
"${templateOption:cloud}",
"${templateOption:login}"
],
"remoteUser": "root",
"customizations": {
"workbench": {
"opens": {
"extensions": [
// Source
".ipynb",
".R",
".py",
// Documents
".md",
".html",
".latex",
".pdf",
// Images
".bmp",
".gif",
".jpeg",
".jpg",
".png",
".svg",
// Data
".csv",
".tsv",
".json",
".vl"
],
"fileUrlSuffix": "/lab/tree/{path}",
"folderUrlSuffix": "/lab/tree/{path}"
}
}
}
}
21 changes: 21 additions & 0 deletions src/workbench-jupyter-parabricks/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Use the official NVIDIA Clara Parabricks container as the base image
FROM nvcr.io/nvidia/clara/clara-parabricks:4.5.1-1

# Set the working directory inside the container
WORKDIR /workspace

# Switch to root user to install packages
USER root

# Update package lists and install python3, pip, and other essentials
# Clean up apt-get cache to reduce image size
RUN apt-get update && \
apt-get install -y python3 python3-pip && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

# Install Jupyter Lab using pip
RUN pip3 install jupyterlab

# Expose the port Jupyter Lab will run on
EXPOSE 8888
23 changes: 23 additions & 0 deletions src/workbench-jupyter-parabricks/devcontainer-template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"id": "custom-workbench-jupyter-parabricks-template",
"description": "A template used to serve the Workbench JupyterLab container image plus NVIDIA Parabricks",
"version": "0.0.1",
"name": "Workbench Prebuilt JupyterLab Template running alongside NVIDIA Parabricks",
"documentationURL": "https://github.com/verily-src/workbench-app-devcontainers/tree/master/src/custom-workbench-jupyter-template",
"licenseURL": "https://github.com/verily-src/workbench-app-devcontainers/blob/master/LICENSE",
"options": {
"cloud": {
"type": "string",
"description": "VM cloud environment",
"proposals": ["gcp", "aws"],
"default": "gcp"
},
"login": {
"type": "string",
"description": "Whether to log in to workbench CLI",
"proposals": ["true", "false"],
"default": "false"
}
},
"platforms": ["Any"]
}
23 changes: 23 additions & 0 deletions src/workbench-jupyter-parabricks/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
version: "2.4"
services:
app:
container_name: "application-server"
image: "us-central1-docker.pkg.dev/wb-quick-seed-877/parabricks-demo-repo/test1:20250827"
user: root
restart: always
volumes:
- .:/workspace:cached
ports:
- "8888:8888"
networks:
- app-network
cap_add:
- SYS_ADMIN
devices:
- /dev/fuse
security_opt:
- apparmor:unconfined
command: jupyter lab --ip=0.0.0.0 --port=8888 --no-browser --allow-root --LabApp.token=''
networks:
app-network:
external: true
2 changes: 1 addition & 1 deletion startupscript/gcp/resource-mount.sh
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,5 @@ fi
sed -i '/user_allow_other/s/^#//g' /etc/fuse.conf

if [[ "${LOG_IN}" == "true" ]]; then
${RUN_AS_LOGIN_USER} "wb resource mount --allow-other || echo 'Resource mounting failed.'"
${RUN_AS_LOGIN_USER} "/'${WORKBENCH_INSTALL_PATH}' resource mount --allow-other || echo 'Resource mounting failed.'"
fi
4 changes: 2 additions & 2 deletions startupscript/git-setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ ${RUN_AS_LOGIN_USER} "mkdir -p ${USER_SSH_DIR} --mode 0700"
# Get the user's SSH key from Workbench, and if set, write it to the user's .ssh directory
${RUN_AS_LOGIN_USER} "\
install --mode 0600 /dev/null '${USER_SSH_DIR}/id_rsa.tmp' && \
wb security ssh-key get --include-private-key --format=JSON >> '${USER_SSH_DIR}/id_rsa.tmp' || true"
'${WORKBENCH_INSTALL_PATH}' security ssh-key get --include-private-key --format=JSON >> '${USER_SSH_DIR}/id_rsa.tmp' || true"
if [[ -s "${USER_SSH_DIR}/id_rsa.tmp" ]]; then
${RUN_AS_LOGIN_USER} "\
install --mode 0600 /dev/null '${USER_SSH_DIR}/id_rsa' && \
Expand Down Expand Up @@ -63,7 +63,7 @@ ${RUN_AS_LOGIN_USER} "mkdir -p '${WORKBENCH_GIT_REPOS_DIR}'"

# shellcheck disable=SC2164
pushd "${WORKBENCH_GIT_REPOS_DIR}"
${RUN_AS_LOGIN_USER} "wb resource list --type=GIT_REPO --format json" | \
${RUN_AS_LOGIN_USER} "'${WORKBENCH_INSTALL_PATH}' resource list --type=GIT_REPO --format json" | \
jq -c .[] | \
while read -r ITEM; do
GIT_REPO_NAME="$(echo "$ITEM" | jq -r .id)"
Expand Down
16 changes: 8 additions & 8 deletions startupscript/install-cli.sh
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ fi
readonly TERRA_SERVER

# Only install cli if not already installed
if ! command -v wb &> /dev/null; then
if ! command -v '${WORKBENCH_INSTALL_PATH}'&> /dev/null; then
emit "Installing the Workbench CLI ..."

if ! AXON_VERSION_URL="$(get_axon_version_url "${TERRA_SERVER}")"; then
Expand All @@ -69,21 +69,21 @@ if ! command -v wb &> /dev/null; then
cp wb "${WORKBENCH_INSTALL_PATH}"

# Copy 'wb' to its legacy 'terra' name.
cp "${WORKBENCH_INSTALL_PATH}" "${WORKBENCH_LEGACY_PATH}"
cp wb "${WORKBENCH_LEGACY_PATH}"
fi

# Set browser manual login since that's the only login supported from a Vertex AI Notebook VM
${RUN_AS_LOGIN_USER} "wb config set browser MANUAL"
${RUN_AS_LOGIN_USER} "'${WORKBENCH_INSTALL_PATH}' config set browser MANUAL"

# Set the CLI server based on the server that created the VM.
${RUN_AS_LOGIN_USER} "wb server set --name=${TERRA_SERVER}"
${RUN_AS_LOGIN_USER} "'${WORKBENCH_INSTALL_PATH}' server set --name=${TERRA_SERVER}"

# Generate the bash completion script
${RUN_AS_LOGIN_USER} "wb generate-completion > '${USER_BASH_COMPLETION_DIR}/workbench'"
${RUN_AS_LOGIN_USER} "'${WORKBENCH_INSTALL_PATH}' generate-completion > '${USER_BASH_COMPLETION_DIR}/workbench'"

if [[ "${LOG_IN}" == "true" ]]; then

# For GCP use "APP_DEFAULT_CREDENTIALS", for AWS use "AWS_IAM" as --mode arg to "wb auth login".
# For GCP use "APP_DEFAULT_CREDENTIALS", for AWS use "AWS_IAM" as --mode arg to "/usr/bin/wb auth login".
LOG_IN_MODE="APP_DEFAULT_CREDENTIALS"
if [[ "${CLOUD}" == "aws" ]]; then
LOG_IN_MODE="AWS_IAM"
Expand All @@ -92,13 +92,13 @@ if [[ "${LOG_IN}" == "true" ]]; then

# Log in with app-default-credentials
emit "Logging into workbench CLI with mode ${LOG_IN_MODE}"
${RUN_AS_LOGIN_USER} "wb auth login --mode=${LOG_IN_MODE}"
${RUN_AS_LOGIN_USER} "'${WORKBENCH_INSTALL_PATH}' auth login --mode=${LOG_IN_MODE}"

# Set the CLI workspace id using the VM metadata, if set.
TERRA_WORKSPACE="$(get_metadata_value "terra-workspace-id")"
readonly TERRA_WORKSPACE
if [[ -n "${TERRA_WORKSPACE}" ]]; then
${RUN_AS_LOGIN_USER} "wb workspace set --id='${TERRA_WORKSPACE}'"
${RUN_AS_LOGIN_USER} "'${WORKBENCH_INSTALL_PATH}' workspace set --id='${TERRA_WORKSPACE}'"
fi
else
emit "Do not log user into workbench CLI. Manual log in is required."
Expand Down
4 changes: 2 additions & 2 deletions startupscript/remount-on-restart.sh
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ source "${SCRIPT_DIR}/emit.sh"
# CLI login
#############################
readonly RUN_AS_LOGIN_USER="sudo -u ${USER_NAME} bash -l -c"
if [[ "${LOG_IN}" == "true" ]] && ${RUN_AS_LOGIN_USER} "wb auth status 2>&1" | grep -q "NO USER LOGGED IN"; then
${RUN_AS_LOGIN_USER} "wb auth login --mode=APP_DEFAULT_CREDENTIALS"
if [[ "${LOG_IN}" == "true" ]] && ${RUN_AS_LOGIN_USER} "/usr/bin/wb auth status 2>&1" | grep -q "NO USER LOGGED IN"; then
${RUN_AS_LOGIN_USER} "/usr/bin/wb auth login --mode=APP_DEFAULT_CREDENTIALS"
fi

#############################
Expand Down
8 changes: 4 additions & 4 deletions startupscript/setup-bashrc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ emit "Customize user bashrc ..."
if [[ "${LOG_IN}" == "true" ]]; then
# OWNER_EMAIL is really the Workbench user account email address
OWNER_EMAIL="$(
${RUN_AS_LOGIN_USER} "wb workspace describe --format=json" | \
${RUN_AS_LOGIN_USER} "''${WORKBENCH_INSTALL_PATH}'' workspace describe --format=json" | \
jq --raw-output ".userEmail")"
readonly OWNER_EMAIL

# PET_SA_EMAIL is the pet service account for the Workbench user and
# is specific to the GCP project backing the workspace
PET_SA_EMAIL="$(
${RUN_AS_LOGIN_USER} "wb auth status --format=json" | \
${RUN_AS_LOGIN_USER} "'${WORKBENCH_INSTALL_PATH}' auth status --format=json" | \
jq --raw-output ".serviceAccountEmail")"
readonly PET_SA_EMAIL

Expand All @@ -57,7 +57,7 @@ if [[ "${CLOUD}" == "gcp" && "${LOG_IN}" == "true" ]]; then

# GOOGLE_PROJECT is the project id for the GCP project backing the workspace
GOOGLE_PROJECT="$(
${RUN_AS_LOGIN_USER} "wb workspace describe --format=json" | \
${RUN_AS_LOGIN_USER} "'${WORKBENCH_INSTALL_PATH}' workspace describe --format=json" | \
jq --raw-output ".googleProjectId")"
readonly GOOGLE_PROJECT

Expand All @@ -77,7 +77,7 @@ if [[ "${CLOUD}" == "aws" && "${LOG_IN}" == "true" ]]; then

# Create a symlink to this workspace's AWS config file to use as the target for AWS_CONFIG_FILE.
readonly AWS_CONFIG_SYMLINK="${USER_WORKBENCH_CONFIG_DIR}/workspace.conf"
${RUN_AS_LOGIN_USER} "eval \$(wb workspace configure-aws) && \
${RUN_AS_LOGIN_USER} "eval \$('${WORKBENCH_INSTALL_PATH}' workspace configure-aws) && \
ln -sf \${AWS_CONFIG_FILE} ${AWS_CONFIG_SYMLINK}"

emit "Adding Workbench AWS-sepcific environment variables to ~/.bashrc ..."
Expand Down