From 06cf264b3551675ddfe7b942efe69d8402c699f4 Mon Sep 17 00:00:00 2001 From: Rob Ballantyne Date: Tue, 24 Oct 2023 09:09:03 +0100 Subject: [PATCH] Update base --- .../supervisord/conf.d/jupyter.conf | 8 +- .../opt/ai-dock/bin/build/layer0/common.sh | 2 +- .../opt/ai-dock/bin/supervisor-jupyter.sh | 132 ++++++++++-------- build/Dockerfile | 1 + docker-compose.yaml | 27 ++-- 5 files changed, 93 insertions(+), 77 deletions(-) diff --git a/build/COPY_ROOT/etc/supervisor/supervisord/conf.d/jupyter.conf b/build/COPY_ROOT/etc/supervisor/supervisord/conf.d/jupyter.conf index 859759c..249487b 100644 --- a/build/COPY_ROOT/etc/supervisor/supervisord/conf.d/jupyter.conf +++ b/build/COPY_ROOT/etc/supervisor/supervisord/conf.d/jupyter.conf @@ -5,7 +5,7 @@ numprocs=1 directory=/root priority=1000 autostart=true -startsecs=5 +startsecs=0 startretries=3 autorestart=unexpected stopsignal=TERM @@ -15,7 +15,7 @@ killasgroup=true stdout_logfile=/var/log/supervisor/jupyter.log stdout_logfile_maxbytes=10MB stdout_logfile_backups=1 -stderr_logfile=/var/log/supervisor/jupyter.error.log -stderr_logfile_maxbytes=10MB -stderr_logfile_backups=1 +stderr_logfile=/dev/null +stderr_logfile_maxbytes=0 +stderr_logfile_backups=0 environment=PROC_NAME="%(program_name)s" \ No newline at end of file diff --git a/build/COPY_ROOT/opt/ai-dock/bin/build/layer0/common.sh b/build/COPY_ROOT/opt/ai-dock/bin/build/layer0/common.sh index a016dd9..c3df884 100755 --- a/build/COPY_ROOT/opt/ai-dock/bin/build/layer0/common.sh +++ b/build/COPY_ROOT/opt/ai-dock/bin/build/layer0/common.sh @@ -11,7 +11,7 @@ main() { } install_jupyter() { - $MAMBA_CREATE -n jupyter -c conda-forge python=${MAMBA_BASE_PYTHON_VERSION} + $MAMBA_CREATE -n jupyter -c conda-forge python=3.10 micromamba -n jupyter install -c conda-forge -y \ jupyter \ jupyterlab \ diff --git a/build/COPY_ROOT/opt/ai-dock/bin/supervisor-jupyter.sh b/build/COPY_ROOT/opt/ai-dock/bin/supervisor-jupyter.sh index 541736a..91ae0f6 100755 --- a/build/COPY_ROOT/opt/ai-dock/bin/supervisor-jupyter.sh +++ b/build/COPY_ROOT/opt/ai-dock/bin/supervisor-jupyter.sh @@ -11,69 +11,77 @@ function cleanup() { rm /run/http_ports/$PROXY_PORT > /dev/null 2>&1 } -if [[ -z $JUPYTER_MODE || ! "$JUPYTER_MODE" = "notebook" ]]; then - JUPYTER_MODE="lab" -fi - -if [[ -z $JUPYTER_PORT ]]; then - JUPYTER_PORT=8888 -fi - -PROXY_PORT=$JUPYTER_PORT -SERVICE_NAME="Jupyter ${JUPYTER_MODE^}" - -file_content="$( - jq --null-input \ - --arg listen_port "${LISTEN_PORT}" \ - --arg metrics_port "${METRICS_PORT}" \ - --arg proxy_port "${PROXY_PORT}" \ - --arg proxy_secure "${PROXY_SECURE,,}" \ - --arg service_name "${SERVICE_NAME}" \ - '$ARGS.named' -)" - -printf "%s" "$file_content" > /run/http_ports/$PROXY_PORT - -# Delay launch until micromamba is ready -if [[ -f /run/workspace_moving ]]; then - /usr/bin/python3 /opt/ai-dock/fastapi/logviewer/main.py \ - -p $LISTEN_PORT \ - -r 5 \ - -s "${SERVICE_NAME}" \ - -t "Preparing ${SERVICE_NAME}" & - fastapi_pid=$! +function start() { + if [[ -z $JUPYTER_MODE || ! "$JUPYTER_MODE" = "notebook" ]]; then + JUPYTER_MODE="lab" + fi + + if [[ -z $JUPYTER_PORT ]]; then + JUPYTER_PORT=8888 + fi + + PROXY_PORT=$JUPYTER_PORT + SERVICE_NAME="Jupyter ${JUPYTER_MODE^}" + + if [[ ${SERVERLESS,,} = "true" ]]; then + printf "Refusing to start $SERVICE_NAME service in serverless mode\n" + exit 0 + fi - while [[ -f /run/workspace_moving ]]; do - sleep 1 - done + file_content="$( + jq --null-input \ + --arg listen_port "${LISTEN_PORT}" \ + --arg metrics_port "${METRICS_PORT}" \ + --arg proxy_port "${PROXY_PORT}" \ + --arg proxy_secure "${PROXY_SECURE,,}" \ + --arg service_name "${SERVICE_NAME}" \ + '$ARGS.named' + )" - printf "\nStarting %s... " ${SERVICE_NAME:-service} - kill $fastapi_pid & + printf "%s" "$file_content" > /run/http_ports/$PROXY_PORT + + # Delay launch until micromamba is ready + if [[ -f /run/workspace_moving ]]; then + /usr/bin/python3 /opt/ai-dock/fastapi/logviewer/main.py \ + -p $LISTEN_PORT \ + -r 5 \ + -s "${SERVICE_NAME}" \ + -t "Preparing ${SERVICE_NAME}" & + fastapi_pid=$! + + while [[ -f /run/workspace_moving ]]; do + sleep 1 + done + + printf "\nStarting %s... " ${SERVICE_NAME:-service} + kill $fastapi_pid & + wait -n + printf "OK\n" + else + printf "Starting %s...\n" ${SERVICE_NAME} + fi + + kill -9 $(lsof -t -i:$LISTEN_PORT) > /dev/null 2>&1 & wait -n - printf "OK\n" -else - printf "Starting %s...\n" ${SERVICE_NAME} -fi - -kill -9 $(lsof -t -i:$LISTEN_PORT) > /dev/null 2>&1 & -wait -n - -printf "Starting Jupyter %s...\n" ${JUPYTER_MODE^} - -micromamba run -n jupyter jupyter \ - $JUPYTER_MODE \ - --allow-root \ - --ip=127.0.0.1 \ - --port=$LISTEN_PORT \ - --no-browser \ - --ServerApp.token='' \ - --ServerApp.password='' \ - --ServerApp.trust_xheaders=True \ - --ServerApp.disable_check_xsrf=False \ - --ServerApp.allow_remote_access=True \ - --ServerApp.allow_origin='*' \ - --ServerApp.allow_credentials=True \ - --ServerApp.root_dir=$WORKSPACE \ - --ServerApp.preferred_dir=$WORKSPACE \ - --KernelSpecManager.ensure_native_kernel=False + + printf "Starting Jupyter %s...\n" ${JUPYTER_MODE^} + + micromamba run -n jupyter jupyter \ + $JUPYTER_MODE \ + --allow-root \ + --ip=127.0.0.1 \ + --port=$LISTEN_PORT \ + --no-browser \ + --ServerApp.token='' \ + --ServerApp.password='' \ + --ServerApp.trust_xheaders=True \ + --ServerApp.disable_check_xsrf=False \ + --ServerApp.allow_remote_access=True \ + --ServerApp.allow_origin='*' \ + --ServerApp.allow_credentials=True \ + --ServerApp.root_dir=$WORKSPACE \ + --ServerApp.preferred_dir=$WORKSPACE \ + --KernelSpecManager.ensure_native_kernel=False +} +start 2>&1 diff --git a/build/Dockerfile b/build/Dockerfile index 4d26a27..40a470a 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -8,6 +8,7 @@ LABEL org.opencontainers.image.description "Jupyter lab/notebook with Python ker LABEL maintainer="Rob Ballantyne " +ENV OPT_SYNC=$OPT_SYNC ENV IMAGE_SLUG="jupyter-python" # Add new paths at front diff --git a/docker-compose.yaml b/docker-compose.yaml index ea1f14c..ed6bc1b 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -39,7 +39,7 @@ services: - /etc/group:/etc/group:ro - ./config/rclone:/etc/rclone # Workspace - - ./workspace:${WORKSPACE}:rshared + - ./workspace:${WORKSPACE:-/workspace}:rshared # Will echo to root-owned authorized_keys file; # Avoids changing local file owner - ./config/authorized_keys:/root/.ssh/authorized_keys_mount @@ -47,19 +47,26 @@ services: ports: # SSH available on host machine port 2222 to avoid conflict. Change to suit - - ${SSH_PORT_HOST}:${SSH_PORT} + - ${SSH_PORT_HOST:-2222}:${SSH_PORT:-22} + # Web UI for easy service access + - ${REDIRECTOR_PORT_HOST:-1111}:1111 + # Websocket log viewer + - ${LOG_VIEWER_PORT_HOST:-1122}:1122 # Jupyter server - - ${JUPYTER_PORT_HOST}:${JUPYTER_PORT} + - ${JUPYTER_PORT_HOST:-8888}:8888 # Rclone webserver for interactive configuration - - ${RCLONE_PORT_HOST}:53682 + - ${RCLONE_PORT_HOST:-53682}:53682 environment: # Don't enclose values in quotes - - JUPYTER_PORT=${JUPYTER_PORT} - - JUPYTER_TOKEN=${JUPYTER_TOKEN} # Allows running true SSH alongside provider proxy SSH - - SSH_PORT=${SSH_PORT} - - WORKSPACE=${WORKSPACE} - - CF_TUNNEL_TOKEN=${CF_TUNNEL_TOKEN} - - CF_QUICK_TUNNELS=${CF_QUICK_TUNNELS} + - SSH_PORT=${SSH_PORT:-22} + - WORKSPACE=${WORKSPACE:-/workspace} + - WORKSPACE_SYNC=${WORKSPACE_SYNC:-true} + - CF_TUNNEL_TOKEN=${CF_TUNNEL_TOKEN:-} + - CF_QUICK_TUNNELS=${CF_QUICK_TUNNELS:-true} + - WEB_ENABLE_AUTH=${WEB_ENABLE_AUTH:-true} + - WEB_USER=${WEB_USER:-user} + - WEB_PASSWORD=${WEB_PASSWORD:-password} + - SERVERLESS=${SERVERLESS:-false} #- PROVISIONING_SCRIPT=https://raw.githubusercontent.com/ai-dock/jupyter-python/main/config/provisioning/default.sh