Skip to content

Instantly share code, notes, and snippets.

@darkarnium
Last active March 14, 2024 14:25
Show Gist options
  • Save darkarnium/b8f7a68fa78f387d8bd55e2076cdf381 to your computer and use it in GitHub Desktop.
Save darkarnium/b8f7a68fa78f387d8bd55e2076cdf381 to your computer and use it in GitHub Desktop.
JupyterLab - Local setup
#!/bin/bash
# If the lab container version changes, plugins and their associated Python dependencies
# may need updating.
LAB_CONTAINER="jupyter/base-notebook:lab-4.0.7"
function wait_for_jupyterlab {
while true ; do
if curl -s -m5 -o /dev/null -f http://127.0.0.1:8888; then
break
fi
echo -n "."
sleep 1
done
}
# Ensure the required directory structure exists.
mkdir -p "${PWD}/jupyterlab/work"
mkdir -p "${PWD}/jupyterlab/configuration"
mkdir -p "${PWD}/jupyterlab/start-up"
# Create the requirements list, if not present.
if [ ! -e "${PWD}/jupyterlab/requirements.txt" ]; then
cat > "${PWD}/jupyterlab/requirements.txt" <<EOF
requests
boto3
jmespath
python-lsp-server[all]
black
isort
jupyterlab-lsp==5.1.0
jupyterlab_code_formatter==2.2.1
EOF
fi
# Create the package bootstrap script, if not present.
if [ ! -e "${PWD}/jupyterlab/start-up/packages.sh" ]; then
cat > "${PWD}/jupyterlab/start-up/packages.sh" <<EOF
#!/bin/sh
pip install -r /home/jupyter/requirements.txt
EOF
chmod a+x "${PWD}/jupyterlab/start-up/packages.sh"
fi
# Flag whether a restart is required after start-up. This is used as some extensions
# require a full restart of JupterLab before they will function. We set this based on
# the installation of configuration, rather than the plugin itself, for simplicity but
# at the cost of accuracy if no configuration is added for a given plugin.
JL_RECONFIG=0
# Install advanced settings, if not present.
CF_SETTINGS="${PWD}/jupyterlab/configuration/lab/user-settings/@ryantam626/jupyterlab_code_formatter/settings.jupyterlab-settings"
NE_SETTINGS="${PWD}/jupyterlab/configuration/lab/user-settings/@jupyterlab/notebook-extension/tracker.jupyterlab-settings"
EM_SETTINGS="${PWD}/jupyterlab/configuration/lab/user-settings/@jupyterlab/extensionmanager-extension/plugin.jupyterlab-settings"
if [ ! -e "${CF_SETTINGS}" ]; then
mkdir -p "$(dirname "${CF_SETTINGS}")"
JL_RECONFIG=1
cat > "${CF_SETTINGS}" <<EOF
{
"formatOnSave": true,
"preferences": {
"default_formatter": {
"python": ["isort", "black"]
}
}
}
EOF
fi
if [ ! -e "${NE_SETTINGS}" ]; then
mkdir -p "$(dirname "${NE_SETTINGS}")"
JL_RECONFIG=1
cat > "${NE_SETTINGS}" <<EOF
{
"codeCellConfig": {
"rulers": [88]
}
}
EOF
fi
if [ ! -e "${EM_SETTINGS}" ]; then
mkdir -p "$(dirname "${EM_SETTINGS}")"
JL_RECONFIG=1
cat > "${EM_SETTINGS}" <<EOF
{
"disclaimed": true
}
EOF
fi
# No container? Start one.
if ! docker start JupyterLab > /dev/null 2>&1; then
docker run \
-itd \
--name JupyterLab \
--user root \
-p 127.0.0.1:8888:8888 \
-e GRANT_SUDO=yes \
-e NB_USER=jupyter \
-w /home/jupyter/ \
-e CHOWN_HOME=yes \
-e JUPYTER_ENABLE_LAB=yes \
-e RESTARTABLE=yes \
-v"${PWD}/jupyterlab/work":/home/jupyter/work \
-v"${PWD}/jupyterlab/configuration":/home/jupyter/.jupyter \
-v"${PWD}/jupyterlab/requirements.txt":/home/jupyter/requirements.txt \
-v"${PWD}/jupyterlab/start-up":/usr/local/bin/start-notebook.d/ \
"${LAB_CONTAINER}"
fi
# Get token and print to STDOUT.
echo -n 'INFO: Waiting for JupyterLab to start...'
wait_for_jupyterlab
echo "DONE"
# If the JupterLab configuration has been changed, restart the container to make sure
# everything is correct.
if [ $JL_RECONFIG -gt 0 ]; then
echo -n 'INFO: JupterLab restarting due to configuration change...'
docker restart JupyterLab > /dev/null 2>&1
wait_for_jupyterlab
fi
echo "DONE"
# Grab the JupyterLab token / URL.
echo -n 'INFO: Fetching JupyterLab token from logs...'
JUPYTER_URL=$(docker logs JupyterLab | grep -Eio 'http.*?token=[0-9a-f]+' | tail -n 1)
echo "DONE"
# Finally good to go!
echo "INFO: JupyterLab available at ${JUPYTER_URL}"
echo 'INFO: Attempting to open JupyterLab in browser...'
if [ -n "$(which open)" ]; then
open "${JUPYTER_URL}"
else
echo "INFO: No 'open' on this system, not opening browser."
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment