diff --git a/README.md b/README.md index a0cfcb5..2bd72f8 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,11 @@ It is a good idea to leave the source tree alone and copy any edits you would li As this overlaying happens after the main build, it is easy to add extra files such as ML models and datasets to your images. You will also be able to rebuild quickly if your file overrides are made here. +Any directories and files that you add into `opt/storage` will be made available in the running container at `$WORKSPACE/storage`. + +This directory is monitored by `inotifywait`. Any items appearing in this directory will be automatically linked to the application directories as defined in `/opt/ai-dock/storage_monitor/etc/mappings.sh`. This is particularly useful if you need to run several applications that each need to make use of the stored files. + + ## Run Locally A 'feature-complete' `docker-compose.yaml` file is included for your convenience. All features of the image are included - Simply edit the environment variables in `.env`, save and then type `docker compose up`. @@ -134,7 +139,7 @@ You can use the included `cloudflared` service to make secure connections withou | `PROVISIONING_SCRIPT` | URL of a remote script to execute on init. See [note](#provisioning-script). | | `RCLONE_*` | Rclone configuration - See [rclone documentation](https://rclone.org/docs/#config-file) | | `SKIP_ACL` | Set `true` to skip modifying workspace ACL | -| `SSH_PORT` | Set a non-standard port for SSH (default `22`) | +| `SSH_PORT_LOCAL` | Set a non-standard port for SSH (default `22`) | | `SSH_PUBKEY` | Your public key for SSH | | `WEB_ENABLE_AUTH` | Enable password protection for web services (default `true`) | | `WEB_USER` | Username for web services (default `user`) | @@ -174,7 +179,7 @@ The URL must point to a plain text file - GitHub Gists/Pastebin (raw) are suitab If you are running locally you may instead opt to mount a script at `/opt/ai-dock/bin/provisioning.sh`. >[!NOTE] ->If configured, `sshd`, `cloudflared`, `rclone` & `logtail` will be launched before provisioning; Any other processes will launch after. +>If configured, `sshd`, `caddy`, `cloudflared`, `rclone`, `jupyter`, `serviceportal`, `storagemonitor` & `logtail` will be launched before provisioning; Any other processes will launch after. >[!WARNING] >Only use scripts that you trust and which cannot be changed without your consent. @@ -344,6 +349,10 @@ This script follows and prints the log files for each of the above services to s If you are logged into the container you can follow the logs by running `logtail.sh` in your shell. +### Storage Monitor + +This service detects changes to files in `$WORKSPACE/storage` and creates symbolic links to the application directories defined in `/opt/ai-dock/storage_monitor/etc/mappings.sh` + ## Open Ports Some ports need to be exposed for the services to run or for certain features of the provided software to function @@ -376,7 +385,7 @@ Some ports need to be exposed for the services to run or for certain features of - Select `Advanced options` - In Container Name enter `ghcr.io/ai-dock/jupyter-pytorch:latest` - In Registry Username enter `x` (Paperspace bug) -- In Command enter `init.sh WORKSPACE=/notebooks` +- In Command enter `init.sh WORKSPACE=/notebooks CF_QUICK_TUNNELS=true TUNNEL_TRANSPORT_PROTOCOL=http2 WEB_USER=user WEB_PASSWORD=password` >[!WARNING] >Do not attempt to use tunnels to circumvent Paperspace restrictions (eg. SSH & private networking) - You will lose your account. 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 3571e4b..e048754 100755 --- a/build/COPY_ROOT/opt/ai-dock/bin/supervisor-jupyter.sh +++ b/build/COPY_ROOT/opt/ai-dock/bin/supervisor-jupyter.sh @@ -2,25 +2,28 @@ trap cleanup EXIT -LISTEN_PORT=18888 -METRICS_PORT=28888 -PROXY_SECURE=true - function cleanup() { kill $(jobs -p) > /dev/null 2>&1 rm /run/http_ports/$PROXY_PORT > /dev/null 2>&1 } function start() { - if [[ -z $JUPYTER_MODE || ! "$JUPYTER_MODE" = "notebook" ]]; then - JUPYTER_MODE="notebook" + LISTEN_PORT=${JUPYTER_PORT_LOCAL:-18888} + METRICS_PORT=${JUPYTER_METRICS_PORT:-28888} + PROXY_SECURE=true + + if [[ ! -v JUPYTER_PORT || -z $JUPYTER_PORT ]]; then + JUPYTER_PORT=${JUPYTER_PORT_HOST:-8888} fi + PROXY_PORT=$JUPYTER_PORT - if [[ -z $JUPYTER_PORT ]]; then - JUPYTER_PORT=8888 + if [[ ! -v JUPYTER_MODE || -z $JUPYTER_MODE ]]; then + JUPYTER_MODE="notebook" + fi + if [[ $JUPYTER_MODE != "notebook" ]]; then + JUPYTER_MODE="lab" fi - PROXY_PORT=$JUPYTER_PORT SERVICE_NAME="Jupyter ${JUPYTER_MODE^}" if [[ ${SERVERLESS,,} = "true" ]]; then @@ -78,7 +81,7 @@ function start() { --ServerApp.allow_credentials=True \ --ServerApp.root_dir=$WORKSPACE \ --ServerApp.preferred_dir=$WORKSPACE \ - --KernelSpecManager.ensure_native_kernel=False + --KernelSpecManager.ensure_native_kernel=False } start 2>&1 diff --git a/build/COPY_ROOT_EXTRA/.gitkeep b/build/COPY_ROOT_EXTRA/opt/storage/.gitkeep similarity index 100% rename from build/COPY_ROOT_EXTRA/.gitkeep rename to build/COPY_ROOT_EXTRA/opt/storage/.gitkeep diff --git a/docker-compose.yaml b/docker-compose.yaml index d384c9b..4e639e5 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -56,20 +56,18 @@ services: ports: # SSH available on host machine port 2222 to avoid conflict. Change to suit - - ${SSH_PORT_HOST:-2222}:${SSH_PORT:-22} - # Web UI for easy service access - - ${REDIRECTOR_PORT_HOST:-1111}:1111 + - ${SSH_PORT_HOST:-2222}:${SSH_PORT_LOCAL:-22} + # Caddy port for service portal + - ${SERVICEPORTAL_PORT_HOST:-1111}:${SERVICEPORTAL_PORT_HOST:-1111} # Jupyter server - - ${JUPYTER_PORT_HOST:-8888}:${JUPYTER_PORT:-8888} + - ${JUPYTER_PORT_HOST:-8888}:${JUPYTER_PORT_HOST:-8888} # Rclone webserver for interactive configuration - - ${RCLONE_PORT_HOST:-53682}:53682 + - ${RCLONE_PORT_HOST:-53682}:${RCLONE_PORT_HOST:-53682} environment: # Don't enclose values in quotes - DIRECT_ADDRESS=${DIRECT_ADDRESS:-127.0.0.1} - DIRECT_ADDRESS_GET_WAN=${DIRECT_ADDRESS_GET_WAN:-false} - - JUPYTER_PORT=${JUPYTER_PORT:-8888} - - SSH_PORT=${SSH_PORT:-22} - WORKSPACE=${WORKSPACE:-/workspace} - WORKSPACE_SYNC=${WORKSPACE_SYNC:-true} - CF_TUNNEL_TOKEN=${CF_TUNNEL_TOKEN:-} @@ -77,5 +75,13 @@ services: - WEB_ENABLE_AUTH=${WEB_ENABLE_AUTH:-true} - WEB_USER=${WEB_USER:-user} - WEB_PASSWORD=${WEB_PASSWORD:-password} + - SSH_PORT_HOST=${SSH_PORT_HOST:-2222} + - SSH_PORT_LOCAL=${SSH_PORT_LOCAL:-22} + - SERVICEPORTAL_PORT_HOST=${SERVICEPORTAL_PORT_HOST:-1111} + - SERVICEPORTAL_PORT_LOCAL=${SERVICEPORTAL_PORT_LOCAL:-11111} + - SERVICEPORTAL_METRICS_PORT=${SERVICEPORTAL_METRICS_PORT:-21111} + - JUPYTER_PORT_HOST=${JUPYTER_PORT_HOST:-8888} + - JUPYTER_PORT_LOCAL=${JUPYTER_PORT_LOCAL:-18888} + - JUPYTER_METRICS_PORT=${JUPYTER_METRICS_PORT:-28888} - SERVERLESS=${SERVERLESS:-false} #- PROVISIONING_SCRIPT=https://raw.githubusercontent.com/ai-dock/jupyter-pytorch/main/config/provisioning/default.sh