21e865ffb0
Espone la GUI Streamlit su https://cerbero-bite.tielogic.xyz tramite il Traefik già attivo sull'host (label allineate al pattern di cerbero-mcp, TLS via Let's Encrypt, websocket pass-through). Aggiunge: - nuova tab `📚 Strategia` con stato live dei gate §2 confrontati con l'ultimo tick di market_snapshots, pannello P/L parametrico affiancato Conservativa vs Aggressiva, tabella di sensibilità win-rate → APR e rendering del documento canonico esteso. - doc `13-strategia-spiegata.md` che lega ogni regola §2-§9 al campo di market_snapshots che la alimenta, con sezioni §4-bis (P/L atteso realistico, win-rate empirico, drawdown, Sharpe) e §4-ter (confronto fra i due profili e quando passare dall'uno all'altro). - `strategy.conservativa.yaml` (golden config v1.0.0 esplicita) e `strategy.aggressiva.yaml` (cap_per_trade 4×, max_concurrent 2×, max_contracts 4×, deroga §11 documentata) con config_hash validi. - nel compose: servizio dedicato `cerbero-bite-gui` (Streamlit su 0.0.0.0:8765, healthcheck su /_stcore/health, label Traefik), env condivisi via anchor YAML `x-bite-env`, `--environment mainnet` passato a `start` per allineare il boot check al token del .env (era testnet vs mainnet → kill switch armato all'avvio). - Dockerfile installa anche l'extra `gui` (streamlit) e copia `docs/` + i due nuovi profili nell'immagine; `.dockerignore` non esclude più `docs/` (causa del primo build silenzioso). Fix bonus: `_try_load` nella pagina ritornava `LoadedConfig` ma la GUI leggeva `.sizing.*` direttamente — l'`except: pass` mascherava l'AttributeError facendo cadere sui default conservativi sia nel pannello P/L sia nello stato gate (stesso pattern presente nella Calibrazione). Ora ritorna `.config`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
133 lines
5.1 KiB
YAML
133 lines
5.1 KiB
YAML
# docker-compose.yml — Cerbero Bite
|
|
#
|
|
# Bite runs in its own Compose project but joins the same Docker
|
|
# network used by Cerbero MCP V2 and Traefik (`traefik`) so it can
|
|
# either resolve the in-cluster service name (`cerbero-mcp:9000`)
|
|
# or reach the public gateway (`https://cerbero-mcp.tielogic.xyz`)
|
|
# transparently.
|
|
#
|
|
# The reverse-proxy network (`traefik`) is declared as external
|
|
# here. It is created by the Traefik stack at /opt/docker/traefik
|
|
# and shared by every web-facing service on the host.
|
|
#
|
|
# Authentication: a single bearer token is passed through from the
|
|
# host `.env` file via `CERBERO_BITE_MCP_TOKEN`. The Cerbero MCP V2
|
|
# server uses the token to decide whether the upstream environment
|
|
# is testnet or mainnet; switching environment = switching token.
|
|
#
|
|
# Two services are defined:
|
|
# * `cerbero-bite` — the trading engine / CLI worker
|
|
# * `cerbero-bite-gui` — the Streamlit dashboard, exposed by
|
|
# Traefik at https://cerbero-bite.<DOMAIN>
|
|
|
|
networks:
|
|
traefik:
|
|
external: true
|
|
|
|
volumes:
|
|
bite-data:
|
|
|
|
x-bite-env: &bite-env
|
|
CERBERO_BITE_MCP_TOKEN: ${CERBERO_BITE_MCP_TOKEN:?missing CERBERO_BITE_MCP_TOKEN}
|
|
CERBERO_BITE_MCP_BOT_TAG: ${CERBERO_BITE_MCP_BOT_TAG:-BOT__CERBERO_BITE}
|
|
# Two independent runtime flags that decide what each cycle does.
|
|
# Initial period ("data-only"): DATA_ANALYSIS=true, STRATEGY=false.
|
|
CERBERO_BITE_ENABLE_DATA_ANALYSIS: ${CERBERO_BITE_ENABLE_DATA_ANALYSIS:-true}
|
|
CERBERO_BITE_ENABLE_STRATEGY: ${CERBERO_BITE_ENABLE_STRATEGY:-false}
|
|
# Service URLs — defaults below match the in-cluster Traefik network
|
|
# DNS (V2 unified image listening on port 9000). Override any of
|
|
# them via .env to point at the public gateway, a custom host, or
|
|
# localhost for dev work.
|
|
CERBERO_BITE_MCP_DERIBIT_URL: ${CERBERO_BITE_MCP_DERIBIT_URL:-http://cerbero-mcp:9000/mcp-deribit}
|
|
CERBERO_BITE_MCP_HYPERLIQUID_URL: ${CERBERO_BITE_MCP_HYPERLIQUID_URL:-http://cerbero-mcp:9000/mcp-hyperliquid}
|
|
CERBERO_BITE_MCP_MACRO_URL: ${CERBERO_BITE_MCP_MACRO_URL:-http://cerbero-mcp:9000/mcp-macro}
|
|
CERBERO_BITE_MCP_SENTIMENT_URL: ${CERBERO_BITE_MCP_SENTIMENT_URL:-http://cerbero-mcp:9000/mcp-sentiment}
|
|
|
|
services:
|
|
cerbero-bite:
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile
|
|
image: cerbero-bite:dev
|
|
restart: unless-stopped
|
|
networks: [traefik]
|
|
cap_drop: [ALL]
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
environment:
|
|
<<: *bite-env
|
|
# Telegram and Portfolio are no longer shared MCP services. The
|
|
# bot now calls the Telegram Bot API directly and aggregates
|
|
# portfolio in-process from Deribit + Hyperliquid + Macro.
|
|
# Set the two env vars below to enable Telegram notifications.
|
|
# CERBERO_BITE_TELEGRAM_BOT_TOKEN: ...
|
|
# CERBERO_BITE_TELEGRAM_CHAT_ID: ...
|
|
volumes:
|
|
- bite-data:/app/data
|
|
healthcheck:
|
|
test:
|
|
["CMD", "cerbero-bite", "healthcheck", "--db", "/app/data/state.sqlite"]
|
|
interval: 60s
|
|
timeout: 5s
|
|
retries: 3
|
|
start_period: 120s
|
|
# Engine main loop (scheduler + monitoring). Switch to `status`,
|
|
# `ping`, `dry-run`, ... for one-shot diagnostics. The MCP token in
|
|
# `.env` decides the upstream environment server-side; the `start`
|
|
# flag below tells the local boot check what to expect (must match,
|
|
# otherwise the engine arms the kill switch).
|
|
command: ["start", "--environment", "mainnet"]
|
|
|
|
# Streamlit dashboard published by Traefik on
|
|
# https://cerbero-bite.${DOMAIN_NAME:-tielogic.xyz}
|
|
#
|
|
# The CLI sub-command `cerbero-bite gui` hard-codes the listen
|
|
# address to 127.0.0.1, so we bypass the entrypoint and invoke
|
|
# Streamlit directly. The two `CERBERO_BITE_GUI_*` env vars match
|
|
# what the CLI normally injects (see src/cerbero_bite/cli.py).
|
|
cerbero-bite-gui:
|
|
image: cerbero-bite:dev
|
|
restart: unless-stopped
|
|
depends_on:
|
|
- cerbero-bite
|
|
networks: [traefik]
|
|
cap_drop: [ALL]
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
environment:
|
|
<<: *bite-env
|
|
CERBERO_BITE_GUI_DB: /app/data/state.sqlite
|
|
CERBERO_BITE_GUI_AUDIT: /app/data/log/audit.jsonl
|
|
volumes:
|
|
- bite-data:/app/data
|
|
entrypoint:
|
|
- python
|
|
- -m
|
|
- streamlit
|
|
- run
|
|
- /app/src/cerbero_bite/gui/main.py
|
|
- --server.address=0.0.0.0
|
|
- --server.port=8765
|
|
- --server.headless=true
|
|
- --browser.gatherUsageStats=false
|
|
command: []
|
|
healthcheck:
|
|
test:
|
|
- "CMD"
|
|
- "python"
|
|
- "-c"
|
|
- "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8765/_stcore/health', timeout=3).close()"
|
|
interval: 30s
|
|
timeout: 5s
|
|
retries: 3
|
|
start_period: 30s
|
|
labels:
|
|
- traefik.enable=true
|
|
- traefik.docker.network=traefik
|
|
- "traefik.http.routers.cerbero-bite.rule=Host(`cerbero-bite.${DOMAIN_NAME:-tielogic.xyz}`)"
|
|
- traefik.http.routers.cerbero-bite.tls=true
|
|
- traefik.http.routers.cerbero-bite.entrypoints=websecure
|
|
- traefik.http.routers.cerbero-bite.tls.certresolver=mytlschallenge
|
|
- traefik.http.services.cerbero-bite.loadbalancer.server.port=8765
|
|
- com.centurylinklabs.watchtower.enable=true
|