Portfolio_Risk_Management/deploy/docker-compose.quantcore.yml
herzogflorian b5da424dfe quantcore: standalone Apptainer setup for students' DGX Sparks
The portfolio data, risk and mean-CVaR optimisation service, prepared for
students who run it on their own DGX Spark without root, Docker or Tailscale.

- deploy/apptainer/qc.sh: install, start/stop/status/logs, cli/api/python,
  data import/export and Yahoo setup/update. cuOpt and quantcore run as two
  Apptainer instances of the user and talk over 127.0.0.1; the API and the
  test bench listen on 127.0.0.1 only. Builds quantcore.sif without root, or
  falls back to a plain Python image plus a virtualenv when the Spark allows
  no unprivileged builds. Detects taken ports and suggests free ones.
- deploy/apptainer/quantcore.def + constraints.txt: the image, with the
  library versions of the verified production container pinned.
- cuOpt under Apptainer: NVIDIA's image sets HOME=/opt/cuopt, read-only in a
  SIF, so the solver died on its first job; qc.sh gives it a writable home.
- solvers: a cuOpt that disappears during a solve now falls back to HiGHS
  instead of answering 500 (requests' ConnectionError escaped the fallback).
- client: idempotent GETs retry a dropped keep-alive connection, which made
  `quantcore-api update --wait` fail when a poll met uvicorn's 5 s timeout.
- config: cuOpt defaults to http://127.0.0.1:5000 and `quantcore serve` to
  127.0.0.1; the Docker images keep passing their own values.
- docs/SPARK_APPTAINER.md: the students' guide; README, USAGE, ARCHITECTURE
  and SPARK_DEPLOYMENT point to it.

Tested on a DGX Spark (GB10, Apptainer 1.5.4, unprivileged user) in both
modes: selftest on every endpoint, optimisation on cuOpt, Yahoo update,
port conflicts; 139 tests pass in the container against the live cuOpt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 09:55:28 +02:00

27 lines
1.1 KiB
YAML

# Service block for the DGX Spark's ~/services/docker-compose.yml (deploy/deploy_to_spark.sh
# appends it). Standalone use: docker compose -f deploy/docker-compose.quantcore.yml up -d
#
# The service reaches cuOpt through the compose network (http://cuopt:5000) and keeps all its
# data under ~/services/work/quantcore_data on the host (survives rebuilds and restarts).
services:
quantcore:
build:
context: ./work/Portfolio_Risk_Optimization # the rsynced repository
dockerfile: deploy/Dockerfile
image: local/quantcore:0.1
container_name: quantcore
restart: unless-stopped
ports: ["5001:5001"]
environment:
QUANTCORE_DATA_DIR: /data
QUANTCORE_CUOPT_URL: http://cuopt:5000
QUANTCORE_CUOPT_TIME_LIMIT: "300"
QUANTCORE_LOG_LEVEL: INFO
QUANTCORE_ENABLE_UI: "true" # "false" for an installation whose users bring their own front end
OPENBLAS_NUM_THREADS: "4" # small-matrix linear algebra is much slower with 20 threads
OMP_NUM_THREADS: "4"
volumes:
- ./work/quantcore_data:/data
depends_on:
- cuopt