From f55e4f00c5cbba2eb562df95986d12d072799fb3 Mon Sep 17 00:00:00 2001 From: Adriano Dal Pastro Date: Fri, 15 May 2026 18:59:14 +0000 Subject: [PATCH] fix(deploy): rimuovi PYTHONPATH, member come runtime deps, StripPrefix per NiceGUI subpath MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- Dockerfile | 8 ++++++-- docker-compose.yml | 6 ++++++ pyproject.toml | 9 +++++++-- uv.lock | 12 ++++++++---- 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/Dockerfile b/Dockerfile index cd5cace..18e77c6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -37,8 +37,12 @@ COPY scripts ./scripts ENV PATH="/app/.venv/bin:$PATH" \ PYTHONUNBUFFERED=1 \ - PYTHONDONTWRITEBYTECODE=1 \ - PYTHONPATH=/app/src + PYTHONDONTWRITEBYTECODE=1 +# 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 \ && mkdir -p /app/data /app/series /app/state /app/strategies \ diff --git a/docker-compose.yml b/docker-compose.yml index 7008000..9e80445 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -109,4 +109,10 @@ services: - traefik.http.routers.strategy-crypto-gui.entrypoints=websecure - traefik.http.routers.strategy-crypto-gui.tls.certresolver=mytlschallenge - "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 diff --git a/pyproject.toml b/pyproject.toml index 756c244..5e0daed 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,6 +4,13 @@ version = "0.1.0" description = "Multi-Swarm Coevolutive: monorepo workspace (core + strategie)" authors = [{ name = "Adriano Dal Pastro", email = "adrianodalpastro@tielogic.com" }] 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] members = ["src/multi_swarm_core", "src/strategy_crypto"] @@ -21,8 +28,6 @@ dev = [ "ruff>=0.7", "mypy>=1.13", "types-requests>=2.32", - "multi-swarm-core", - "strategy-crypto", ] [tool.ruff] diff --git a/uv.lock b/uv.lock index 73b728b..c64a9b6 100644 --- a/uv.lock +++ b/uv.lock @@ -897,32 +897,36 @@ wheels = [ name = "multi-swarm-coevolutive" version = "0.1.0" source = { virtual = "." } +dependencies = [ + { name = "multi-swarm-core" }, + { name = "strategy-crypto" }, +] [package.dev-dependencies] dev = [ - { name = "multi-swarm-core" }, { name = "mypy" }, { name = "pytest" }, { name = "pytest-asyncio" }, { name = "pytest-mock" }, { name = "responses" }, { name = "ruff" }, - { name = "strategy-crypto" }, { name = "types-requests" }, ] [package.metadata] +requires-dist = [ + { name = "multi-swarm-core", editable = "src/multi_swarm_core" }, + { name = "strategy-crypto", editable = "src/strategy_crypto" }, +] [package.metadata.requires-dev] dev = [ - { name = "multi-swarm-core", editable = "src/multi_swarm_core" }, { name = "mypy", specifier = ">=1.13" }, { name = "pytest", specifier = ">=8.3" }, { name = "pytest-asyncio", specifier = ">=0.24" }, { name = "pytest-mock", specifier = ">=3.14" }, { name = "responses", specifier = ">=0.25" }, { name = "ruff", specifier = ">=0.7" }, - { name = "strategy-crypto", editable = "src/strategy_crypto" }, { name = "types-requests", specifier = ">=2.32" }, ]