fix(deploy): rimuovi PYTHONPATH, member come runtime deps, StripPrefix per NiceGUI subpath
Tre fix di deploy emersi al primo build/up del nuovo compose: 1. Dockerfile: rimosso PYTHONPATH=/app/src Con layout uv workspace doppio-nest, PYTHONPATH=/app/src faceva ombra alla venv risolvendo le member-dir (multi_swarm_core/, strategy_crypto/) come namespace packages PEP 420 senza i sub-package del codice (cerbero, persistence, frontend, ecc.). I package sono installati come editable dal `uv sync --frozen` nella venv: niente PYTHONPATH necessario. 2. pyproject root: aggiunto [project] dependencies = [multi-swarm-core, strategy-crypto] I due member workspace erano in [dependency-groups.dev], escluse da `uv sync --frozen --no-dev` del builder Docker -> "ModuleNotFoundError: No module named multi_swarm_core". Spostati come dipendenze runtime del deployable app root; dev group ora contiene solo pytest/ruff/mypy. uv.lock rigenerato. 3. docker-compose.yml: aggiunto Traefik middleware StripPrefix NiceGUI con root_path="/strategy_crypto_gui" assume che il proxy strippi il prefix prima di girare al container (FastAPI route restano "/", "/paper", ecc.). Senza StripPrefix, NiceGUI riceveva "/strategy_crypto_gui/" e rispondeva 404. Aggiunte 2 label: - strategy-crypto-stripprefix middleware - router.middlewares = strategy-crypto-stripprefix Verifica end-to-end: - https://swarm.tielogic.xyz/strategy_crypto_gui/ -> HTTP 200 (31KB) - https://swarm.tielogic.xyz/ -> HTTP 404 (root libera, atteso) - paper run phase3-baseline-001 (fcf271d0...) tick=1 OK, $1000 equity - state/strategy_crypto.db creato con 5 tabelle paper_trading_* NB: permission fix per `src/strategy_crypto/strategy_crypto/strategies/` fatto manualmente (chown 1000:1000) — i JSON migrati da git mv erano root:root, container gira come uid 1000. Annotare per future strategies. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+6
-2
@@ -37,8 +37,12 @@ COPY scripts ./scripts
|
|||||||
|
|
||||||
ENV PATH="/app/.venv/bin:$PATH" \
|
ENV PATH="/app/.venv/bin:$PATH" \
|
||||||
PYTHONUNBUFFERED=1 \
|
PYTHONUNBUFFERED=1 \
|
||||||
PYTHONDONTWRITEBYTECODE=1 \
|
PYTHONDONTWRITEBYTECODE=1
|
||||||
PYTHONPATH=/app/src
|
# NO PYTHONPATH: con uv workspace + layout doppio-nest, PYTHONPATH=/app/src
|
||||||
|
# farebbe ombra alla venv risolvendo le member-dir (multi_swarm_core/,
|
||||||
|
# strategy_crypto/) come namespace packages senza i sub-package del codice.
|
||||||
|
# I pacchetti sono installati come editable dal `uv sync --frozen` del builder
|
||||||
|
# e risolvibili direttamente via /app/.venv/.
|
||||||
|
|
||||||
RUN useradd -m -u 1000 app \
|
RUN useradd -m -u 1000 app \
|
||||||
&& mkdir -p /app/data /app/series /app/state /app/strategies \
|
&& mkdir -p /app/data /app/series /app/state /app/strategies \
|
||||||
|
|||||||
@@ -109,4 +109,10 @@ services:
|
|||||||
- traefik.http.routers.strategy-crypto-gui.entrypoints=websecure
|
- traefik.http.routers.strategy-crypto-gui.entrypoints=websecure
|
||||||
- traefik.http.routers.strategy-crypto-gui.tls.certresolver=mytlschallenge
|
- traefik.http.routers.strategy-crypto-gui.tls.certresolver=mytlschallenge
|
||||||
- "traefik.http.services.strategy-crypto-gui.loadbalancer.server.port=${SWARM_DASHBOARD_PORT:-8080}"
|
- "traefik.http.services.strategy-crypto-gui.loadbalancer.server.port=${SWARM_DASHBOARD_PORT:-8080}"
|
||||||
|
# StripPrefix: rimuove /strategy_crypto_gui prima di girare al container.
|
||||||
|
# NiceGUI ha root_path=/strategy_crypto_gui per generare link assoluti corretti
|
||||||
|
# (lato browser), ma le route FastAPI interne restano "/", "/paper", ecc. —
|
||||||
|
# quindi il prefix esterno DEVE essere stripped dal proxy.
|
||||||
|
- "traefik.http.middlewares.strategy-crypto-stripprefix.stripprefix.prefixes=/strategy_crypto_gui"
|
||||||
|
- "traefik.http.routers.strategy-crypto-gui.middlewares=strategy-crypto-stripprefix"
|
||||||
- com.centurylinklabs.watchtower.enable=true
|
- com.centurylinklabs.watchtower.enable=true
|
||||||
|
|||||||
+7
-2
@@ -4,6 +4,13 @@ version = "0.1.0"
|
|||||||
description = "Multi-Swarm Coevolutive: monorepo workspace (core + strategie)"
|
description = "Multi-Swarm Coevolutive: monorepo workspace (core + strategie)"
|
||||||
authors = [{ name = "Adriano Dal Pastro", email = "adrianodalpastro@tielogic.com" }]
|
authors = [{ name = "Adriano Dal Pastro", email = "adrianodalpastro@tielogic.com" }]
|
||||||
requires-python = ">=3.13"
|
requires-python = ">=3.13"
|
||||||
|
# I due workspace member sono dipendenze runtime del deployable app root.
|
||||||
|
# Cosi' `uv sync --frozen --no-dev` (nel builder Docker) li installa entrambi
|
||||||
|
# come editable nella venv senza tirare pytest/ruff/mypy.
|
||||||
|
dependencies = [
|
||||||
|
"multi-swarm-core",
|
||||||
|
"strategy-crypto",
|
||||||
|
]
|
||||||
|
|
||||||
[tool.uv.workspace]
|
[tool.uv.workspace]
|
||||||
members = ["src/multi_swarm_core", "src/strategy_crypto"]
|
members = ["src/multi_swarm_core", "src/strategy_crypto"]
|
||||||
@@ -21,8 +28,6 @@ dev = [
|
|||||||
"ruff>=0.7",
|
"ruff>=0.7",
|
||||||
"mypy>=1.13",
|
"mypy>=1.13",
|
||||||
"types-requests>=2.32",
|
"types-requests>=2.32",
|
||||||
"multi-swarm-core",
|
|
||||||
"strategy-crypto",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[tool.ruff]
|
[tool.ruff]
|
||||||
|
|||||||
@@ -897,32 +897,36 @@ wheels = [
|
|||||||
name = "multi-swarm-coevolutive"
|
name = "multi-swarm-coevolutive"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = { virtual = "." }
|
source = { virtual = "." }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "multi-swarm-core" },
|
||||||
|
{ name = "strategy-crypto" },
|
||||||
|
]
|
||||||
|
|
||||||
[package.dev-dependencies]
|
[package.dev-dependencies]
|
||||||
dev = [
|
dev = [
|
||||||
{ name = "multi-swarm-core" },
|
|
||||||
{ name = "mypy" },
|
{ name = "mypy" },
|
||||||
{ name = "pytest" },
|
{ name = "pytest" },
|
||||||
{ name = "pytest-asyncio" },
|
{ name = "pytest-asyncio" },
|
||||||
{ name = "pytest-mock" },
|
{ name = "pytest-mock" },
|
||||||
{ name = "responses" },
|
{ name = "responses" },
|
||||||
{ name = "ruff" },
|
{ name = "ruff" },
|
||||||
{ name = "strategy-crypto" },
|
|
||||||
{ name = "types-requests" },
|
{ name = "types-requests" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.metadata]
|
[package.metadata]
|
||||||
|
requires-dist = [
|
||||||
|
{ name = "multi-swarm-core", editable = "src/multi_swarm_core" },
|
||||||
|
{ name = "strategy-crypto", editable = "src/strategy_crypto" },
|
||||||
|
]
|
||||||
|
|
||||||
[package.metadata.requires-dev]
|
[package.metadata.requires-dev]
|
||||||
dev = [
|
dev = [
|
||||||
{ name = "multi-swarm-core", editable = "src/multi_swarm_core" },
|
|
||||||
{ name = "mypy", specifier = ">=1.13" },
|
{ name = "mypy", specifier = ">=1.13" },
|
||||||
{ name = "pytest", specifier = ">=8.3" },
|
{ name = "pytest", specifier = ">=8.3" },
|
||||||
{ name = "pytest-asyncio", specifier = ">=0.24" },
|
{ name = "pytest-asyncio", specifier = ">=0.24" },
|
||||||
{ name = "pytest-mock", specifier = ">=3.14" },
|
{ name = "pytest-mock", specifier = ">=3.14" },
|
||||||
{ name = "responses", specifier = ">=0.25" },
|
{ name = "responses", specifier = ">=0.25" },
|
||||||
{ name = "ruff", specifier = ">=0.7" },
|
{ name = "ruff", specifier = ">=0.7" },
|
||||||
{ name = "strategy-crypto", editable = "src/strategy_crypto" },
|
|
||||||
{ name = "types-requests", specifier = ">=2.32" },
|
{ name = "types-requests", specifier = ">=2.32" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user