feat(proxy): run multiple local shops in parallel behind a shared proxy - #1208
feat(proxy): run multiple local shops in parallel behind a shared proxy#1208Tomasz Turkowski (tturkowski) wants to merge 250 commits into
Conversation
…ments are provided
…logs and sections
# Conflicts: # go.mod
- Calculate max overlay lines based on terminal height instead of fixed 10 - Change overlay sizing from percentage (80%) to absolute dimensions - Add overlayMaxLines() function for responsive log buffer
# Conflicts: # cmd/project/project_create.go # go.mod
Rework the Instance tab log handling so each source keeps its own scrollback and switching between them no longer discards output. All sources now stream in the background via a tagged fan-in channel, so returning to a source shows its previous logs. Sidebar arrow-key navigation now follows the visual group order (containers, processes, files) instead of raw discovery order, running processes render a hollow dot distinct from the active source's solid dot, and stopping a watcher removes its entry from the sidebar.
Show only the relevant Start or Stop entry per watcher in the command palette based on its current state, instead of listing both. A watcher counts as active when running or starting, so the palette drops from four watcher rows to two.
* feat(devtui): redesign overview tab with setup health report Split the overview into a two-column layout: a readonly project report on the left and a "User action" column with the watchers on the right, with a stacked fallback for narrow terminals. - Merge Admin Access and Services into one Access table with the Shop Admin login as the first row; credential-less services show "no auth" - Add a Setup health report: PHP version and memory limit read from the project's PHP runtime via the executor, admin worker and Flow Builder log level resolved from config/packages for the project's APP_ENV - Move background processing to the left column and render it with the same status dots as the health checks - Make all URLs and health check names clickable OSC 8 hyperlinks in the shared underlined link style; check names open the relevant docs page - Drop arrow-key focusing of services; only the watchers remain focusable * fix(devtui): resolve golangci-lint findings in overview health rendering * fix(devtui): address Codex review findings on overview layout - Raise the two-column breakpoint to 110 so the Access table cannot wrap into the right column on 100-107 column terminals - Refresh discovered services and setup-health checks after a config save restarts the containers, instead of showing stale runtime values
) * feat(devtui): track usage telemetry for setup flows and dashboard Add anonymous usage events to the project dev TUI so we can see where the setup wizards lose users, whether Docker environments start reliably, and which dashboard features are used: - project.dev.install: install wizard outcome incl. abandoned step, failed deployment-helper step, and chosen language/currency - project.dev.migration_wizard: replaces migration_wizard_completed, now also reporting cancelled (with step) and failed runs - project.dev.docker_start: compose up duration and result, for both initial startup and config-change restarts - project.dev.action: command-palette actions with task result/duration - project.dev.watcher: per-watcher-run uptime and end reason - project.dev.health: one-per-session setup-health snapshot (levels only) - project.dev.session: session duration, tabs visited, action counts, and stop-containers vs keep-running exit choice All state lives in a nil-safe telemetryState shared across Model copies; outcome events latch so quit paths cannot double-report. No URLs, credentials, or free-text input are ever sent. Events are documented in docs/TELEMETRY.md, and a package TestMain sets DO_NOT_TRACK so tests never emit real events. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix: resolve golangci-lint issues Check the os.Setenv error in TestMain, make the healthLevel switch exhaustive, and extract watcher message handling from Model.Update into updateWatcherMsg to bring its cyclomatic complexity back under the limit. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(devtui): report in-flight config restarts on quit, extract tag constants Address PR review feedback: - A config-change container restart still in flight when the user leaves the dashboard is now reported as a cancelled docker_start event from shutdown() instead of being silently dropped (matching the initial-start quit path). - Extract the result / watcher-end / exit tag string values into constants in telemetry.go so call sites can't drift apart. Tests keep asserting the literal wire values on purpose. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * refactor(tracking): centralize event name and tag key constants Move all telemetry event names, tag keys, and shared result values into internal/tracking (tracking.Event*, tracking.Tag*, tracking.Result*) so every Track caller — cmd/root.go, project create/upgrade-check, and the dev TUI — shares one vocabulary instead of scattered string literals. The devtui package keeps only its domain-specific tag values (watcher end reasons, session exit choices). Tests still assert the raw wire strings on purpose. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * refactor(devtui): align telemetry tags with ClickHouse materialized columns The analytics events table materializes result and duration_ms columns from tags, so events benefit from reusing those keys: - watcher: uptime_ms -> duration_ms - session: exit -> result (stop_containers / keep_running / quit) - health: instead of one event with dynamic per-check keys (whose php_version key collided with the migration wizard's php_version value tag), send one event per check tagged check + result Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
project create verified Docker/PHP/Composer availability up front, but project dev did not, so cloning an existing project and running dev failed with raw executor errors instead of actionable guidance. Extract the check into system.ValidateProjectDependencies and run it when setting up the dev environment (dev, dev start/stop/status), based on the resolved environment type. The rendered help text is now parameterized so each command phrases the action and the Docker switch hint appropriately. Claude-Session: https://claude.ai/code/session_01PkMbTc3KbdJ9bPN8W52ix7 Co-authored-by: Claude <noreply@anthropic.com>
…inner (#1172) * feat(project): support live dependency installation logs toggle in spinner Allows users to toggle dependency installation logs during project creation using Ctrl+L. Extracted the spinner with logs viewport into a reusable component under internal/tui package. * fix(tui): resolve makezero linter error in progress spinner
When a project ships a local phpstan.neon whose excludePaths fully excludes one of the detected source directories, PHPStan prints a plain text "No files found to analyse." message instead of JSON. This caused project validate --only=phpstan to report a confusing unmarshal error. Skip such directories instead, and include PHPStan's stdout in the unmarshal error message when stderr is empty so remaining failures are diagnosable. Fixes #833 Claude-Session: https://claude.ai/code/session_01Sh7Kd4repLWbXhDXkn5ZXw Co-authored-by: Claude <noreply@anthropic.com>
The formatter re-indented the children of every element, which changed the rendered output of <pre> and <textarea> — their content is whitespace-sensitive per HTML rules. Emit the children of these tags byte-for-byte instead, including nested elements and Twig control structures, which are rendered inline without inserting or removing any whitespace. Claude-Session: https://claude.ai/code/session_015NdDBo9srRM7QULuNyigtT Co-authored-by: Claude <noreply@anthropic.com>
The go-composer metadata includes branch dev builds like "6.7.12.x-dev". These parse cleanly and satisfy the version constraint, so they leaked into the interactive patch-version picker. The previous dev filter only skipped the "dev-" prefix, missing the ".x-dev" suffix form. Skip versions whose prerelease is "dev" so only installable stable/RC releases are offered. Passing a dev version explicitly still resolves. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
4f04d9f to
4b3b422
Compare
Adds `shopware-cli project proxy` (setup/up/down/list/status/verify/ teardown): a shared Traefik container routes stable hostnames like https://shop1.shopware.local to local projects, so shops publish no host ports and any number can run at once. - embedded wildcard DNS server (x/net/dns) on 127.0.0.1:53535, wired via /etc/resolver (macOS) or systemd-resolved (Linux) by a one-time `proxy setup` with a single sudo ceremony (--domain, --skip-trust) - trusted HTTPS out of the box: mkcert-compatible local CA, per-project wildcard SANs, trust-store install via smallstep/truststore - proxy mode is a marker-guarded compose.override.yaml (ports cleared with !reset, requires Compose >= 2.24); the base compose.yaml stays untouched, so `project dev` and manual docker compose keep working in both modes - `up` points APP_URL, the sales channel domain and the url keys in .shopware-project.yml at the proxy; `down` restores everything exactly - `verify` checks the whole chain bottom-up with actionable hints, including guidance when sudo is blocked or systemd-resolved is missing - docs/proxy.md explains the architecture, decisions and trade-offs Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
4b3b422 to
ab10413
Compare
|
Whats definitively missing here is:
|
Dev watchers through the shared proxyA quick summary of how the admin/storefront watchers can work behind the shared reverse proxy. Admin watcher — works as-is, no code changesThe admin is Vite-only. Vite works out its own HMR connection from the page it's loaded on, so all that was needed:
You open Storefront watcher (now) — webpack + a small runtime patchThe storefront's classic watcher (HMR + webpack, Rather than patching vendor file, we inject a tiny preload script when launching the watcher (Node Result: the storefront watcher runs fully through the proxy - multiple shops in parallel, clean port-free hostnames, no exposed ports, and no change to Shopware or the shop. You browse Tradeoff: it's a runtime patch — clever but hidden, and it leans on the internals of Storefront watcher (future) — Vite, the clean pathFrom 6.7.11 the storefront also ships a Vite dev server. To make that work behind a reverse proxy we need a small, fully backward-compatible contribution to
With that, the storefront watcher - once enabled, works at the shop's own URL ( Plan proposal:
|
|
btw because of excactly those REASONS I DONT WANT TO have those watchers directly inside Shopware. we're like now screwed |
What changed?
New command group
shopware-cli project proxy— run any number of local shops in parallel under stable hostnames, instead of everyone fighting over127.0.0.1:8000.proxy setup--domain,--skip-trust)proxy up/downproxy list/statusproxy verifyproxy teardownUnder the hood: one shared Traefik container routes by hostname (shops publish no host ports at all), a tiny DNS server embedded in the binary answers
*.shopware.local → 127.0.0.1, and an mkcert-compatible local CA provides trusted HTTPS. Proxy mode is a marker-guardedcompose.override.yaml— the basecompose.yamlstays untouched, soproject devand manualdocker composekeep working.uppointsAPP_URL, the sales-channel domain and the project config at the proxy;downrestores every value exactly.➡️ Architecture, design decisions and trade-offs:
docs/proxy.mdWhy?
The dev environment publishes fixed host ports, so a second shop can't start — anyone working on multiple projects juggles ports or stops shops. Routing by hostname removes the conflict by construction, and trusted HTTPS matters for testing payment providers locally.
How was this tested?
go test ./...green,golangci-lint run ./...— 0 issuesup/down/teardowncycles with byte-identical restore of.shopware-project.yml,.env.localand the sales-channel domain;verifyladder validated against a real corporate sudo-block scenarioRelated issue or discussion
Closes #1094, related: #939