Skip to content

fix(ui): pause host-proxy site when its dev-server worker is stopped (502 fix)#670

Merged
geodro merged 2 commits into
lerd-env:mainfrom
prabowosd:fix/host-proxy-stop-vhost-502
Jun 29, 2026
Merged

fix(ui): pause host-proxy site when its dev-server worker is stopped (502 fix)#670
geodro merged 2 commits into
lerd-env:mainfrom
prabowosd:fix/host-proxy-stop-vhost-502

Conversation

@prabowosd

@prabowosd prabowosd commented Jun 29, 2026

Copy link
Copy Markdown
Member

Fixes #671.

Problem

Stopping a host-proxy site's dev server from the dashboard leaves the site returning 502 Bad Gateway for every request. Reproduced on a secured host-proxy site running a dev server (e.g. pnpm dev): after stopping its app worker the dev-server port is no longer listening, yet a request to the site returns 502.

The vhost is still the live proxy, pointing at the now-dead port:

location / {
    proxy_pass http://host.containers.internal:<dev-port>;
    ...
}

Root cause

A host-proxy site's dev server is the synthesized app worker (config.HostProxyWorkerName), not a framework worker. The dashboard's worker:app:stop action calls WorkerStopForSite, which tears down only the lerd-app-<site> unit. Nothing swaps the proxy vhost, so nginx keeps proxying to the dead port and 502s.

It is also asymmetric: because app is not in any framework's Workers map, the worker:app:start path bails with "worker app not defined", so once stopped there is no per-worker way to bring it back, only lerd start or pause/unpause.

PauseSite already does the right thing for host-proxy sites (GeneratePausedVhost swaps the secured vhost to the paused page and removes the stale -ssl.conf, then reloads), and UnpauseSite restores the proxy vhost and restarts the dev server. Stopping the only thing a host-proxy site runs is, semantically, pausing the site.

Fix

Route the parent app worker's start/stop through PauseSite / UnpauseSite at the dashboard handler (so there is no recursion through WorkerStopForSite):

  • worker:app:stop (parent, host-proxy) -> PauseSite: swaps the vhost to the paused landing page, stops the dev server, marks the site paused. The paused page's Resume button then works because the registry state is consistent.
  • worker:app:start (parent, host-proxy) -> UnpauseSite: restores the proxy vhost and dev server.
  • Other workers, worktree targets (branch set), and non-host-proxy sites keep the plain per-worker path untouched.

The decision is factored into a pure hostProxyAppLifecycleOp helper so the routing is unit-testable without standing up the HTTP handler.

Worktree host-proxy dev servers (worker:app:stop?branch=...) have the same class of issue but no single-worktree pause primitive exists; left for a follow-up and explicitly excluded here (they keep the normal worker path).

Test

TestHostProxyAppLifecycleOp (table-driven) pins the routing: parent app stop -> pause, start -> unpause, and untouched for non-host-proxy sites, other workers, worktree targets, and unknown ops. go build + go vet ./internal/ui clean.

prabowosd and others added 2 commits June 29, 2026 09:35
Stopping a host-proxy site's "app" worker from the dashboard tore down only
the dev-server unit and left the proxy vhost untouched. With the dev server
gone, nginx kept proxying to the now-dead port and every request to the site
returned 502 Bad Gateway. The "app" worker is synthesized (not a framework
worker), so the worker:app:start path could not even restart it, leaving no
symmetric way back.

Route the parent app worker's start/stop through PauseSite/UnpauseSite, which
swap the proxy vhost to the paused landing page (and back) and keep the
registry's paused state consistent so the page's Resume button works. Other
workers, worktree targets, and non-host-proxy sites keep the plain per-worker
path. The routing decision is factored into hostProxyAppLifecycleOp with a
table-driven test.
@geodro geodro merged commit 7d94f0a into lerd-env:main Jun 29, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

macOS: stopping a host-proxy site's dev-server worker leaves the site returning 502

2 participants