03f723f7fc
NiceGUI è la dashboard ufficiale (port 8080, dark/neon palette, 3 pagine:
/, /convergence, /genomes). La porta è ora parametrica via env
SWARM_DASHBOARD_PORT, letta in ui.run() — Docker la usa anche per
healthcheck e label Traefik.
docker-compose.yml: entrypoint del servizio dashboard cambiato da
streamlit a python -m multi_swarm.dashboard.nicegui_app. Default porta
8080 ovunque (.env, .env.example, compose, healthcheck).
Rimossi i file legacy della vecchia GUI Streamlit:
- src/multi_swarm/dashboard/streamlit_app.py
- src/multi_swarm/dashboard/aquarium.py (helper canvas HTML5)
- src/multi_swarm/dashboard/pages/{01_overview,02_ga_convergence,
03_genomes,04_aquarium}.py
- tests/integration/test_streamlit_smoke.py
pyproject.toml: rimossa la dep streamlit; uv.lock rigenerato (10 deps
transitive eliminate: pydeck, watchdog, jsonschema, pillow, ecc.).
README aggiornato (architettura, comando dashboard, sezione Dashboard
ora descrive NiceGUI con riferimento al deploy Docker via Traefik).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
107 lines
3.6 KiB
YAML
107 lines
3.6 KiB
YAML
# docker-compose.yml — Multi-Swarm Coevolutive
|
|
#
|
|
# Due servizi che condividono la stessa immagine `multi-swarm:dev`:
|
|
#
|
|
# * multi-swarm-paper — paper-trading runner long-running
|
|
# (scripts/run_paper_trading.py)
|
|
# * multi-swarm-dashboard — Streamlit dashboard esposta da Traefik
|
|
# su https://swarm.${DOMAIN_NAME:-tielogic.xyz}
|
|
#
|
|
# Entrambi joinano la rete external `traefik` cosi' il client Cerbero
|
|
# risolve direttamente l'host `cerbero-mcp` (porta 9000) senza passare
|
|
# dal gateway pubblico ne' dal TLS.
|
|
#
|
|
# Dati persistenti via bind mount dalla cartella del repo:
|
|
# ./data cache OHLCV intermedia
|
|
# ./series cache parquet per timeframe/symbol
|
|
# ./state contiene runs.db (+ WAL/SHM)
|
|
# ./strategies btc_*.json / eth_*.json letti dal paper runner
|
|
#
|
|
# Secrets (token Cerbero + OpenRouter): caricati da .env via env_file.
|
|
# Le variabili sotto `environment:` sovrascrivono solo i valori che
|
|
# devono cambiare dentro il container (URL interno, path container).
|
|
|
|
networks:
|
|
traefik:
|
|
external: true
|
|
|
|
x-swarm-env: &swarm-env
|
|
# Override: rotta interna verso cerbero-mcp (no TLS, no traefik hop)
|
|
CERBERO_BASE_URL: http://cerbero-mcp:9000
|
|
# Override: path container per persistenza
|
|
DATA_DIR: /app/data
|
|
SERIES_DIR: /app/series
|
|
DB_PATH: /app/state/runs.db
|
|
|
|
services:
|
|
multi-swarm-paper:
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile
|
|
image: multi-swarm:dev
|
|
container_name: multi-swarm-paper
|
|
restart: unless-stopped
|
|
networks: [traefik]
|
|
env_file: .env
|
|
environment:
|
|
<<: *swarm-env
|
|
volumes:
|
|
- ./data:/app/data
|
|
- ./series:/app/series
|
|
- ./state:/app/state
|
|
- ./strategies:/app/strategies:ro
|
|
# Niente HTTP da controllare: ci affidiamo a `restart: unless-stopped`
|
|
# e ai log per la liveness del runner.
|
|
command:
|
|
- python
|
|
- /app/scripts/run_paper_trading.py
|
|
- --name=${PAPER_RUN_NAME:-phase3-papertrade-prod}
|
|
- --initial-capital=${PAPER_INITIAL_CAPITAL:-1000}
|
|
- --fees-bp=${PAPER_FEES_BP:-5.0}
|
|
- --poll-seconds=${PAPER_POLL_SECONDS:-300}
|
|
- --lookback-bars=${PAPER_LOOKBACK_BARS:-500}
|
|
- --strategies-dir=/app/strategies
|
|
labels:
|
|
- com.centurylinklabs.watchtower.enable=true
|
|
|
|
multi-swarm-dashboard:
|
|
image: multi-swarm:dev
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile
|
|
container_name: multi-swarm-dashboard
|
|
restart: unless-stopped
|
|
networks: [traefik]
|
|
env_file: .env
|
|
environment:
|
|
<<: *swarm-env
|
|
volumes:
|
|
# Dashboard legge solo runs.db: mount in read-only
|
|
- ./state:/app/state:ro
|
|
- ./data:/app/data:ro
|
|
- ./series:/app/series:ro
|
|
entrypoint:
|
|
- python
|
|
- -m
|
|
- multi_swarm.dashboard.nicegui_app
|
|
command: []
|
|
healthcheck:
|
|
test:
|
|
- "CMD"
|
|
- "python"
|
|
- "-c"
|
|
- "import os, urllib.request; urllib.request.urlopen(f'http://localhost:{os.environ.get(\"SWARM_DASHBOARD_PORT\",\"8080\")}/', timeout=3).close()"
|
|
interval: 30s
|
|
timeout: 5s
|
|
retries: 3
|
|
start_period: 30s
|
|
labels:
|
|
- traefik.enable=true
|
|
- traefik.docker.network=traefik
|
|
- "traefik.http.routers.multi-swarm-dashboard.rule=Host(`swarm.${DOMAIN_NAME:-tielogic.xyz}`)"
|
|
- traefik.http.routers.multi-swarm-dashboard.tls=true
|
|
- traefik.http.routers.multi-swarm-dashboard.entrypoints=websecure
|
|
- traefik.http.routers.multi-swarm-dashboard.tls.certresolver=mytlschallenge
|
|
- "traefik.http.services.multi-swarm-dashboard.loadbalancer.server.port=${SWARM_DASHBOARD_PORT:-8080}"
|
|
- com.centurylinklabs.watchtower.enable=true
|