mirror of
https://github.com/stellarshenson/stellars-jupyterhub-ds.git
synced 2026-03-08 06:00:29 +00:00
- Add pull_policy: build to jupyterhub service - Forces Docker Compose to use locally built image - Prevents unnecessary pulls from Docker Hub after building Now 'docker compose up' will use the local image built with 'make build'
126 lines
5.1 KiB
YAML
126 lines
5.1 KiB
YAML
# --------------------------------------------------------------------------------------------------
|
|
#
|
|
# Stellars Jupyterhub DS Platform
|
|
# Project Home: https://github.com/stellarshenson/stellars-jupyterhub-ds
|
|
# This compose file support both GPU and non-GPU platforms
|
|
#
|
|
# Jupyter hub - https://localhost/jupyterhub
|
|
#
|
|
# --------------------------------------------------------------------------------------------------
|
|
|
|
services:
|
|
|
|
# Proxy for smart trafic routing to make it possible to host multiple similar containers
|
|
# exposing ports 80, 413 & 8080 to force docker to keep only one traefik service
|
|
# traefik dashboard is available under http://localhost:8080/dashboard
|
|
traefik:
|
|
image: traefik:latest
|
|
container_name: ${COMPOSE_PROJECT_NAME:-stellars-jupyterhub-ds}-traefik
|
|
command:
|
|
- "--entrypoints.web.address=:80"
|
|
- "--entrypoints.websecure.address=:443"
|
|
- "--providers.docker=true"
|
|
- "--providers.docker.exposedbydefault=false"
|
|
- "--api.dashboard=true"
|
|
- "--api.insecure=true"
|
|
- "--providers.file.filename=/mnt/certs/certs.yml" # certificates generated by jupyterlab container
|
|
- "--serverstransport.insecureskipverify=true" # required for https passthrough
|
|
ports:
|
|
- "80:80"
|
|
- "443:443"
|
|
- "8080:8080"
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock:ro # docker socket to use services labels
|
|
- jupyterhub_certs:/mnt/certs # certificates (generated in jupyterhub image)
|
|
depends_on:
|
|
jupyterhub:
|
|
condition: service_healthy
|
|
networks:
|
|
- jupyterhub_network
|
|
restart: unless-stopped
|
|
|
|
# service for management of a series of users and their jupyterlab
|
|
# environments. it is internally managed via a proxy that redirects
|
|
# users to their dedicated environments
|
|
jupyterhub:
|
|
build:
|
|
context: .
|
|
dockerfile: services/jupyterhub/Dockerfile.jupyterhub
|
|
image: stellars/stellars-jupyterhub-ds:latest
|
|
pull_policy: build
|
|
container_name: ${COMPOSE_PROJECT_NAME:-stellars-jupyterhub-ds}-jupyterhub
|
|
volumes:
|
|
- ./config/jupyterhub_config.py:/srv/jupyterhub/jupyterhub_config.py:ro # config file (read only)
|
|
- jupyterhub_certs:/mnt/certs # certificates (generated in jupyterhub image)
|
|
- /var/run/docker.sock:/var/run/docker.sock:rw # docker socket to use spawner
|
|
- jupyterhub_data:/data # database and cookie secrets
|
|
- jupyterhub_shared:/mnt/shared # shared volume across environments
|
|
- /var/run/docker.sock:/var/run/docker.sock:ro # for nvidia autodetection
|
|
environment:
|
|
- JUPYTERHUB_ADMIN=admin # this username will be a JupyterHub admin
|
|
- DOCKER_NOTEBOOK_IMAGE=stellars/stellars-jupyterlab-ds:latest # jupyterlab image to spawn
|
|
- DOCKER_NETWORK_NAME=jupyterhub_network # spawned containers will join this network
|
|
- JUPYTERHUB_BASE_URL=/jupyterhub # default prefix
|
|
- ENABLE_GPU_SUPPORT=2 # gpu status: 0 - disabled, 1 - enabled, 2 - auto-detect
|
|
- ENABLE_JUPYTERHUB_SSL=0 # if using traefik - you do need direct SSL config
|
|
- ENABLE_SERVICE_MLFLOW=1 # enable mlflow for experiment tracking
|
|
- ENABLE_SERVICE_GLANCES=1 # enable resources monitor
|
|
- ENABLE_SERVICE_TENSORBOARD=1 # enable tensorflow training tracker
|
|
- TF_CPP_MIN_LOG_LEVEL=3 # make tensorflow less verbose
|
|
- NVIDIA_AUTODETECT_IMAGE=nvidia/cuda:12.9.1-base-ubuntu24.04 # image with `nvidia-smi` for gpu autodetection
|
|
labels:
|
|
# Enable proxy support from Traefik
|
|
- "traefik.enable=true"
|
|
|
|
# ⚙ Jupyterhub Service (8000)
|
|
- "traefik.http.routers.jupyterhub-rtr.rule=Path(`/jupyterhub`) || PathPrefix(`/jupyterhub/`)"
|
|
- "traefik.http.routers.jupyterhub-rtr.entrypoints=websecure"
|
|
- "traefik.http.routers.jupyterhub-rtr.service=jupyterhub-svc"
|
|
- "traefik.http.routers.jupyterhub-rtr.tls=true"
|
|
- "traefik.http.services.jupyterhub-svc.loadbalancer.server.scheme=http"
|
|
- "traefik.http.services.jupyterhub-svc.loadbalancer.server.port=8000"
|
|
networks:
|
|
- jupyterhub_network
|
|
ports:
|
|
- "8000:8000"
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pgrep -f jupytehub > /dev/null || exit 1"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 10
|
|
start_period: 5s
|
|
restart: unless-stopped
|
|
|
|
## watchtower for automatic docker image refresh
|
|
## exposing port to force docker to allow only one instance of service
|
|
watchtower:
|
|
container_name: ${COMPOSE_PROJECT_NAME:-stellars-jupyterhub-ds}-watchtower
|
|
image: containrrr/watchtower:latest
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock:rw # to control docker and refresh images
|
|
command: --cleanup --schedule "0 0 * * *" # run every day at midnight
|
|
security_opt:
|
|
- seccomp:unconfined #optional
|
|
depends_on:
|
|
jupyterhub:
|
|
condition: service_healthy
|
|
traefik:
|
|
condition: service_started
|
|
ports:
|
|
- "9911:9911"
|
|
networks:
|
|
- jupyterhub_network
|
|
restart: unless-stopped
|
|
privileged: true
|
|
|
|
volumes:
|
|
jupyterhub_data:
|
|
jupyterhub_certs:
|
|
jupyterhub_shared:
|
|
name: jupyterhub_shared
|
|
|
|
networks:
|
|
jupyterhub_network:
|
|
name: jupyterhub_network
|
|
|