From 5be4926885477cee329ca15d153f5832ca48f6cc Mon Sep 17 00:00:00 2001 From: Walter Oggioni Date: Sat, 26 Sep 2026 15:47:16 +0800 Subject: [PATCH] Bundle kaya-otel in the Docker image The tavolo-app otel extra was never installed: requirements.txt was locked without it and the Dockerfile installs the local distributions with --no-deps, so any container with OTEL_ENABLED set died at import with "kaya-otel is not installed". Add the extra's full closure (kaya-otel plus its OpenTelemetry/protobuf dependencies) to the pinned lock and refresh the comments that claimed the extra had to be added separately. --- deploy/k8s/tavolo.yaml | 2 +- docker-compose.yml | 3 ++- server/Dockerfile | 3 ++- server/README.md | 2 +- server/requirements.txt | 50 ++++++++++++++++++++++++++++++++++++++--- 5 files changed, 53 insertions(+), 7 deletions(-) diff --git a/deploy/k8s/tavolo.yaml b/deploy/k8s/tavolo.yaml index 82ac383..839d130 100644 --- a/deploy/k8s/tavolo.yaml +++ b/deploy/k8s/tavolo.yaml @@ -72,7 +72,7 @@ data: # CORS_EXPOSE_HEADERS: "" # CORS_MAX_AGE: "600" # OpenTelemetry (kaya-otel): traces + metrics via OTLP/HTTP, disabled - # unless OTEL_ENABLED is set. Requires the otel extra in the image. + # unless OTEL_ENABLED is set. The image bundles the otel extra. # OTEL_ENABLED: "true" # OTEL_SERVICE_NAME: "tavolo" # OTEL_EXPORTER_OTLP_ENDPOINT: "http://otel-collector.observability:4318" diff --git a/docker-compose.yml b/docker-compose.yml index 6f0ce5b..58f5cbc 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -123,7 +123,8 @@ services: CORS_EXPOSE_HEADERS: ${CORS_EXPOSE_HEADERS:-} CORS_MAX_AGE: ${CORS_MAX_AGE:-} # OpenTelemetry (kaya-otel): disabled unless OTEL_ENABLED is set. - # Requires the otel extra in the image (see server/pyproject.toml). + # The image bundles the otel extra (see packages/tavolo-app/pyproject.toml + # and server/requirements.txt). OTEL_ENABLED: ${OTEL_ENABLED:-} OTEL_SERVICE_NAME: ${OTEL_SERVICE_NAME:-} OTEL_EXPORTER_OTLP_ENDPOINT: ${OTEL_EXPORTER_OTLP_ENDPOINT:-} diff --git a/server/Dockerfile b/server/Dockerfile index 82a66a4..8522511 100644 --- a/server/Dockerfile +++ b/server/Dockerfile @@ -60,7 +60,8 @@ RUN --mount=type=cache,target=/root/.cache/pip \ # The three sibling distributions, installed from the local tree (PEP 420 # namespace packages sharing the `tavolo` namespace). --no-deps: every -# third-party dependency is already pinned in requirements.txt. +# third-party dependency — including the tavolo-app `otel` extra — is +# already pinned in requirements.txt. COPY server/packages/ ./packages/ RUN --mount=type=cache,target=/root/.cache/pip \ /opt/venv/bin/pip install --no-deps ./packages/tavolo-platform ./packages/tavolo-scopone ./packages/tavolo-app diff --git a/server/README.md b/server/README.md index d754088..cfd90fe 100644 --- a/server/README.md +++ b/server/README.md @@ -81,7 +81,7 @@ All configuration comes from environment variables (see `.env.example`): | `CORS_ALLOW_CREDENTIALS` | `false` | `1`/`true`/`yes`/`on` allow cookies/credentials on cross-origin requests | | `CORS_EXPOSE_HEADERS` | unset | Comma-separated response headers exposed to the browser | | `CORS_MAX_AGE` | `600` | Seconds browsers may cache the preflight response | -| `OTEL_ENABLED` | `false` | `1`/`true`/`yes`/`on` enable OpenTelemetry traces and metrics (requires the `otel` extra, i.e. `pip install tavolo-app[otel]`) | +| `OTEL_ENABLED` | `false` | `1`/`true`/`yes`/`on` enable OpenTelemetry traces and metrics (the Docker image bundles the `otel` extra; non-image installs need `pip install tavolo-app[otel]`) | | `OTEL_SERVICE_NAME` | `tavolo` | `service.name` resource attribute of the exported telemetry | | `OTEL_EXPORTER_OTLP_ENDPOINT` | unset | Base URL of an OTLP/HTTP collector (e.g. `http://localhost:4318`); unset uses the exporter default | | `OTEL_EXPORTER_OTLP_HEADERS` | unset | Comma-separated `key=value` headers sent to the collector (e.g. authentication) | diff --git a/server/requirements.txt b/server/requirements.txt index 593c1e3..38e52a3 100644 --- a/server/requirements.txt +++ b/server/requirements.txt @@ -1,15 +1,19 @@ # # This file is autogenerated by pip-compile with Python 3.14 -# by the following command: +# by the following command (run from server/packages/tavolo-app/): # -# pip-compile --allow-unsafe --extra-index-url=https://pypi.org/simple --index-url=https://gitea.woggioni.net/api/packages/woggioni/pypi/simple --output-file=requirements.txt pyproject.toml +# pip-compile --allow-unsafe --extra otel --extra-index-url=https://pypi.org/simple --index-url=https://gitea.woggioni.net/api/packages/woggioni/pypi/simple --output-file=../../requirements.txt pyproject.toml # # NOTE: the tavolo-platform, tavolo-scopone and tavolo-app sibling packages # are NOT pinned here: they are installed from ./packages in the Dockerfile # and in development (pip install -e ./packages/tavolo-platform # -e ./packages/tavolo-scopone -e ./packages/tavolo-app). All of their # third-party dependencies are direct dependencies of tavolo-app, so this -# lock covers the full closure. +# lock covers the full closure. The otel extra (kaya-otel and its +# OpenTelemetry dependencies) IS included, so OTEL_ENABLED works in the +# Docker image; pip-compile cannot resolve the unpublishable sibling +# packages, so regeneration drops them from a copy of the input file (the +# existing pins constrain the rest). # --index-url https://gitea.woggioni.net/api/packages/woggioni/pypi/simple --extra-index-url https://pypi.org/simple @@ -39,6 +43,8 @@ cryptography==50.0.1 # via pyjwt dictdiffer==0.10.0 # via aerich +googleapis-common-protos==1.75.4 + # via opentelemetry-exporter-otlp-proto-http granian==2.8.3 # via # kaya-rsgi @@ -62,6 +68,7 @@ kaya-core==0.0.4 # kaya-cors # kaya-oidc # kaya-openapi + # kaya-otel # kaya-rsgi # kaya-session # tavolo-app (pyproject.toml) @@ -71,6 +78,8 @@ kaya-oidc==0.0.4 # via tavolo-app (pyproject.toml) kaya-openapi==0.0.4 # via tavolo-app (pyproject.toml) +kaya-otel==0.0.4 + # via tavolo-app (pyproject.toml) kaya-rsgi==0.0.4 # via tavolo-app (pyproject.toml) kaya-session==0.0.4 @@ -80,6 +89,35 @@ kaya-session==0.0.4 # tavolo-app (pyproject.toml) kaya-session-redis==0.0.4 # via tavolo-app (pyproject.toml) +opentelemetry-api==1.45.0 + # via + # opentelemetry-exporter-http-transport + # opentelemetry-exporter-otlp-proto-http + # opentelemetry-sdk + # opentelemetry-semantic-conventions +opentelemetry-exporter-http-transport[urllib3]==0.66b0 + # via opentelemetry-exporter-otlp-proto-http +opentelemetry-exporter-otlp-common==0.66b0 + # via opentelemetry-exporter-otlp-proto-http +opentelemetry-exporter-otlp-proto-common==1.45.0 + # via opentelemetry-exporter-otlp-proto-http +opentelemetry-exporter-otlp-proto-http==1.45.0 + # via kaya-otel +opentelemetry-proto==1.45.0 + # via + # opentelemetry-exporter-otlp-proto-common + # opentelemetry-exporter-otlp-proto-http +opentelemetry-sdk==1.45.0 + # via + # kaya-otel + # opentelemetry-exporter-otlp-common + # opentelemetry-exporter-otlp-proto-http +opentelemetry-semantic-conventions==0.66b0 + # via opentelemetry-sdk +protobuf==7.36.2 + # via + # googleapis-common-protos + # opentelemetry-proto pwo==0.1.2 # via # kaya-core @@ -106,4 +144,10 @@ typing-extensions==4.16.0 # via # anyio # kaya-core + # opentelemetry-api + # opentelemetry-exporter-otlp-proto-http + # opentelemetry-sdk + # opentelemetry-semantic-conventions # pwo +urllib3==2.8.0 + # via opentelemetry-exporter-http-transport