589d003e5c
Niente aggiornamenti automatici dell'immagine per un bot di trading: i deploy devono essere deliberati (build + up manuali), non innescati da un push del registry. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
136 lines
5.3 KiB
YAML
136 lines
5.3 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}
|
|
# MCP V2 unified interface (/mcp): get_instruments, get_historical,
|
|
# get_indicators — removed from the per-exchange routers.
|
|
CERBERO_BITE_MCP_UNIFIED_URL: ${CERBERO_BITE_MCP_UNIFIED_URL:-http://cerbero-mcp:9000/mcp}
|
|
|
|
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=false
|