name: spore # Run-only stack using prebuilt images from Docker Hub. No source checkout # needed — download this file, then: # docker compose -f docker-compose.hub.yml up -d # # Override image tags / provider URLs via environment or a .env file. services: spore: image: ${SPORE_IMAGE:-anshsharma2903/spore:latest} container_name: spore pull_policy: always ports: - "5000:5000" depends_on: redis: condition: service_started kernel-dind: condition: service_healthy kernel-image-puller: condition: service_completed_successfully environment: - APP_HOST=0.0.0.0 - FLASK_ENV=production - REDIS_HOST=redis - REDIS_PORT=6379 - ENCRYPTION_KEY=${ENCRYPTION_KEY:-QVC5YEPET9Os5uS4fJRWbnGicEBXO5e_x4DzOkdz_DA=} - SPORE_DATA_DIR=/data - KERNEL_DATA_MOUNT=/data # Kernel Python version is the startup knob. Change it (env or .env) to run # a different sandbox interpreter; the published image tag tracks it. The # matching tag (e.g. spore-kernel:3.11) must exist on the registry. - KERNEL_PYTHON_VERSION=${KERNEL_PYTHON_VERSION:-3.12} - KERNEL_IMAGE=${KERNEL_IMAGE:-${KERNEL_NAMESPACE:-anshsharma2903}/spore-kernel:${KERNEL_PYTHON_VERSION:-3.12}} - KERNEL_HOST=kernel-dind - KERNEL_VOLUME_BIND=/data - DOCKER_HOST=tcp://kernel-dind:2375 # LLM provider endpoints. Defaults target the host; override in .env (or the # in-app Settings UI) when your providers live elsewhere. NOTE: a host # Ollama/LM Studio must listen on 0.0.0.0 (not 127.0.0.1) to be reachable. - OLLAMA_BASE=${OLLAMA_BASE:-http://host.docker.internal:11434} - OLLAMA_ENDPOINT=${OLLAMA_ENDPOINT:-http://host.docker.internal:11434/api/generate} - LMSTUDIO_BASE=${LMSTUDIO_BASE:-http://host.docker.internal:1234} - OPENAI_BASE=${OPENAI_BASE:-https://api.openai.com/v1} # Optional host metrics bridge (run scripts/spore_host_metrics.py on the host). - SPORE_HOST_METRICS_URL=${SPORE_HOST_METRICS_URL:-} - SPORE_HOST_METRICS_TOKEN=${SPORE_HOST_METRICS_TOKEN:-} - SPORE_METRICS_TIMEOUT=${SPORE_METRICS_TIMEOUT:-2.0} volumes: - spore_volumes:/data networks: - backend_net - kernel_net extra_hosts: - "host.docker.internal:host-gateway" restart: unless-stopped redis: image: eqalpha/keydb:latest container_name: spore-redis networks: - backend_net restart: unless-stopped kernel-dind: image: docker:27-dind container_name: spore-kernel-dind privileged: true environment: - DOCKER_TLS_CERTDIR= volumes: - spore_volumes:/data networks: - kernel_net healthcheck: test: ["CMD", "docker", "info"] interval: 10s timeout: 5s retries: 12 start_period: 60s restart: unless-stopped # Pre-pull the kernel image into the DinD daemon so the first notebook kernel # spawns instantly instead of waiting on a ~900MB pull. kernel-image-puller: image: docker:27-cli container_name: spore-kernel-image-puller environment: - DOCKER_HOST=tcp://kernel-dind:2375 command: > sh -c "until docker info >/dev/null 2>&1; do sleep 1; done && docker pull ${KERNEL_IMAGE:-${KERNEL_NAMESPACE:-anshsharma2903}/spore-kernel:${KERNEL_PYTHON_VERSION:-3.12}}" depends_on: - kernel-dind networks: - kernel_net restart: "no" networks: # Redis is isolated here with no egress; only the spore app is attached. backend_net: internal: true # spore <-> kernel-dind link. Not internal so the DinD daemon can pull base # images and spore can reach LLMs/databases. Kernel container isolation is # enforced inside DinD, not by this network. kernel_net: volumes: spore_volumes: