# Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. 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: # access to docker socket to see if service is healthy - /var/run/docker.sock:/var/run/docker.sock:ro # named volume to hold certificates - jupyterhub_certs:/mnt/certs 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: services/jupyterhub dockerfile: Dockerfile.jupyterhub image: stellars/stellars-jupyterhub-ds:latest container_name: ${COMPOSE_PROJECT_NAME:-stellars-jupyterhub-ds}-jupyterhub volumes: # JupyterHub configuration file - ./config/jupyterhub_config.py:/srv/jupyterhub/jupyterhub_config.py:ro # docker socket on the host so we can connect to the daemon from within the container - /var/run/docker.sock:/var/run/docker.sock:rw # bind Docker volume on host for JupyterHub database and cookie secrets - jupyterhub_data:/data # this is where certificates will be generated - jupyterhub_certs:/mnt/certs environment: - JUPYTERHUB_ADMIN=admin # this username will be a JupyterHub admin - DOCKER_NETWORK_NAME=jupyterhub-network # spawned containers will join this network - DOCKER_NOTEBOOK_IMAGE=stellars/stellars-jupyterlab-ds:latest # jupyterlab image to spawn - JUPYTERHUB_BASE_URL=/jupyterhub # default prefix - GPU_SUPPORT_ENABLED=1 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 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 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: networks: jupyterhub-network: name: jupyterhub-network