feat(BA-1982): add traefik app-proxy frontend mode to the TUI installer#12749
feat(BA-1982): add traefik app-proxy frontend mode to the TUI installer#12749Yaminyam wants to merge 6 commits into
Conversation
Automate the manual traefik-mode App Proxy setup (docs/app-proxy/traefik-integration.md) behind the existing installer option, now accepting `--frontend-mode=traefik`: - Run Traefik as a halfstack compose service (`backendai-half-traefik`, gated behind the "traefik" compose profile) with the API entrypoint published at 127.0.0.1:8080 (the worker reconciles routes against it) and the portproxy_10205..10300 entrypoints exposed. - Complete configs/traefik/traefik.halfstack.yml with the `experimental.localPlugins` definition for the appproxy Traefik plugin and a `ping` endpoint used by the container healthcheck; bundle it into the installer resources (configs/traefik.yml symlink). - installer: add FrontendMode.TRAEFIK (the CLI choice list derives from the enum), prepare the Traefik assets before `compose up` (static config copy with the marker-directory substitution, plugin download with a `gh` fallback while the plugin repository is private), append `--profile traefik`, and generate the coordinator/worker traefik configuration in configure_appproxy (`enable_traefik` + `[proxy_coordinator.traefik.etcd]` with namespace "traefik"; worker `frontend_mode = "traefik"` + `[proxy_worker.traefik]` with the port sub-mode). The TCP worker keeps the port-based frontend (Traefik's etcd rootKey is per worker authority). - The last-used-time marker directory is bind-mounted into the container at the same absolute path as on the host because the coordinator hands the worker's marker path verbatim to the Traefik plugin. - Record the chosen frontend mode in ServiceConfig and show traefik-specific instructions in the install report. Verified: the exact tomlkit mutations validate against the actual appproxy pydantic config models (including `enable_traefik` staying inside [proxy_coordinator]); `docker compose config` is valid with and without the profile; an isolated compose run of etcd+traefik with these assets shows both plugins loading and an etcd-written router appearing via the etcd provider. Fixes #5319 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
seedspirit
left a comment
There was a problem hiding this comment.
Overall, the comments are a bit verbose, so please just leave the key points.
| # Enabled only via `install-dev.sh --app-proxy-frontend=traefik` | ||
| # (docker compose --profile traefik). The static configuration and the | ||
| # appproxy traefik plugin are prepared by install-dev.sh before `up`. | ||
| image: traefik:v3.7 |
There was a problem hiding this comment.
Is there a reason why it was set to 3.7?
There was a problem hiding this comment.
This is because 3.7 is the latest minor version among the current stable versions.
There was a problem hiding this comment.
It was the latest stable minor line at implementation time (the plugin only requires Traefik v3.0+ with WASM support), and I verified it empirically with an isolated compose run (both appproxy plugins load, etcd-provider routing works). The v3.7 minor tag keeps patch updates while avoiding an accidental jump to v3.8/v4.
For reference, the pyinfra fleet installer pins v3.3.7 and one internal cluster runs v3.4.4 in production with the same plugin — so if we prefer aligning the dev halfstack with the production-proven line, I'm happy to change the pin to v3.4 (or v3.3). Let me know which you'd prefer.
There was a problem hiding this comment.
The latest working version is best. Version 3.7 seems like the best choice.
Keep only the key points in the traefik-related comments (compose service, static config header, installer constants/docstrings). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…n download The plugin repository went public, so the anonymous curl path is sufficient. Also fail the install loudly when the download/extract exits non-zero instead of continuing silently. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The plugin repository (
Ready for review — the earlier v3.7 pin discussion is resolved above. |
… flags `--frontend-mode traefik` conflated two independent axes: the traffic pattern (port vs wildcard) and the dataplane implementation (builtin vs Traefik). The appproxy worker config supports the full matrix (Traefik has its own port/wildcard sub-modes), and wildcard installs (--fqdn-prefix public setups) previously could not use the Traefik backend at all. - Add `--proxy-backend builtin|traefik`, composing with `--frontend-mode port|wildcard`. `--frontend-mode traefik` stays as a deprecated alias normalized to (port, traefik) at CLI parsing time. - Implement the Traefik wildcard sub-mode: the worker gets `[proxy_worker.traefik]` with `frontend_mode = "wildcard"` and a `wildcard_domain` table, and the installer rewrites the copied Traefik static config to swap the portproxy_* entrypoints for the fixed `domainproxy` entrypoint the coordinator emits wildcard routers on (portproxy_10250 would collide with it on :10250). - Split the compose port publish so :10250 serves either sub-mode. - The normalization also fixes a latent bug where the TCP worker config got `frontend_mode = "traefik"` without a traefik table (the TCP worker always keeps the builtin frontend). Verified: generated traefik tables (both sub-modes) validate against the real appproxy `TraefikConfig` model; the entrypoint rewrite preserves the plugin and etcd-provider config; `docker compose --profile traefik config` passes; pants fmt/lint/check green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Design update in 52a5449: split the traffic pattern and the dataplane backend into orthogonal flags.
Verification: both traefik sub-mode tables validate against the real |
Resolves #5319 (BA-1982)
Summary
Automates the manual traefik-mode App Proxy setup (
docs/app-proxy/traefik-integration.md) in the TUI installer:Traefik runs as a halfstack compose service gated behind the
traefikcompose profile (same pattern as the observability/storage profiles), so default installs are untouched. Supersedes #12744 (same feature originally targeted atinstall-dev.sh, which is planned for deprecation).Changes
docker-compose.halfstack-main.ymlbackendai-half-traefikservice (traefik:v3.7,profiles: ["traefik"]): API entrypoint published at8080(the worker reconciles routes againsthttp://127.0.0.1:{api_port}),10205-10300portproxy entrypoints, healthcheck viatraefik healthcheck --pingconfigs/traefik/traefik.halfstack.ymlexperimental.localPlugins(appproxy Traefik plugin wasm + go) andping: {}; marker-directory placeholder substituted by the installersrc/ai/backend/install/configs/traefik.ymlsrc/ai/backend/install/types.pyFrontendMode.TRAEFIK(CLI choices derive from the enum) +ServiceConfig.frontend_modefor the install reportsrc/ai/backend/install/context.pyprepare_traefik_assets()beforecompose up(static config copy + marker path substitution + plugin download withghCLI fallback while the plugin repo is private);--profile traefik;configure_appproxytraefik branches for the coordinator (enable_traefik+[proxy_coordinator.traefik.etcd], namespacetraefik) and the HTTP worker ([proxy_worker.traefik], port sub-mode,port_range = [10205, 10300])src/ai/backend/install/app.pysrc/ai/backend/install/cli.pyDesign notes
circuit.py→lastusedmarkerpath).rootKeyis per worker authority, and the bundled static config serves the HTTP worker (worker-1). Extending to the TCP worker needs a second rootKey/entrypoint set — left out of scope.DevContextandPackageContextrun the sameinstall_halfstack/configure_appproxypaths, so both install modes are covered.curl404s, so the installer falls back togh release download(developer credentials); when the repo goes public thecurlpath takes over.Verification
enable_traefiklands inside[proxy_coordinator](not a subtable) andport_rangeuses the tuple form (see fix: render tuple-typed config examples as TOML arrays in generated samples #12747 for the sample.toml bug this uncovered).docker compose configvalid with and without thetraefikprofile./ping+ dashboard 200, healthcheck healthy, and a router written undertraefik/worker_worker-1/...in etcd appears via the etcd provider.pants fmt lint checkclean on all touched Python files.backend.ai install --frontend-mode=traefikrun with a live session app end-to-end; reviewer validation welcome.🤖 Generated with Claude Code