fix(infra): exclude serve-static from 'dev.sh up all' (port collision with apps) #261

Merged
julien merged 1 commits from fix/dev-sh-up-all-include-apps into main 2026-06-01 13:07:09 +02:00
Owner

Summary

Fix ./infra/local/dev.sh up all failing on port is already allocated for port 4200: the apps profile (ADR-0030 — Angular dev-server on 4200) and the serve-static profile (Caddy reverse proxy for the production build, also defaulting to 4200) cannot run together. up all expanded to "every profile" without taking that conflict into account.

After this PR, ./infra/local/dev.sh up all brings up the comprehensive dev stack — infra + dbtools + observability + apps — and serve-static stays available via the explicit ./infra/local/dev.sh up serve-static invocation when a developer actually wants to test a production build.

Root cause

dev.compose.yml publishes port 4200 in two services:

  • portal-shell (profile apps): ${SHELL_PORT:-4200}:4200 — Angular dev-server.
  • serve-static (profile serve-static): ${SERVE_STATIC_PORT:-4200}:4200 — Caddy serving the production build.

dev.sh's ALL_PROFILES array was used both as:

  1. the teardown / status / logs scope (so a manually-started profile is still reachable for down and friends), and
  2. the expansion target for up all.

Conflating the two meant up all always tried to start serve-static even when apps was in scope — and the Docker port-publishing collision aborted the whole up.

Fix

Split the two concerns:

# Every profile that exists — teardown / status / logs scope.
ALL_PROFILES=(dbtools observability serve-static apps)

# What `up all` expands to — serve-static excluded.
UP_ALL_PROFILES=(dbtools observability apps)

serve-static stays accessible:

  • via explicit dev.sh up serve-static (the original way),
  • via dev.sh down / status / logs (still in ALL_PROFILES).

Why exclude serve-static from up all rather than apps:

  • apps is the new "no native toolchain" dev mode (ADR-0030) — it is what a comprehensive dev up should boot.
  • serve-static has zero value without a prior nx build --configuration=production (Caddy serves an empty dist/ → 404 everywhere). Auto-starting it in up all would put a 404-machine in the stack by default.
  • The port number can stay at the Angular convention (4200) for the dev-server, which matches the devcontainer's forwardPorts.

What lands

File Change
infra/local/dev.sh Split ALL_PROFILES (teardown scope) and UP_ALL_PROFILES (up all scope). Inline comment explains the exclusion of serve-static. Usage text updated.
infra/README.md Cheat-sheet row for up all clarifies the new behaviour.

Out of scope

The script is environment-agnostic — it works identically when invoked on the local workstation or on vm-dev. Port publishing is on 0.0.0.0 by default, so services are reachable from a remote browser via the VM IP without any script change. The user-visible difference is only the URL host (localhost:4200 locally vs <vm-ip>:4200 from the workstation against the VM). No local-vs-vm mode in the script.

Test plan

  • bash -n infra/local/dev.sh passes.
  • ./infra/local/dev.sh help shows the updated up all description.
  • On vm-dev: ./infra/local/dev.sh up all brings up postgres / redis / otel-collector / pgweb / jaeger / apps-deps (exits 0) / portal-bff / portal-shell / portal-admin without port conflicts; serve-static is not started.
  • ./infra/local/dev.sh up serve-static (explicit) still starts Caddy on 4200, provided apps is not already up.
  • ./infra/local/dev.sh down and status still see serve-static if it was started manually (ALL_PROFILES retains it).

Related

  • Surfaced by the ADR-0030 dockerised dev mode VM validation — up all was added to the user-facing surface in that PR; this PR finishes wiring it.
  • The port collision was flagged as a caveat in the ADR-0030 PR body ("don't run apps and serve-static together"). This PR turns the caveat into a script invariant instead of relying on the user to remember.
## Summary Fix `./infra/local/dev.sh up all` failing on `port is already allocated` for port 4200: the `apps` profile (ADR-0030 — Angular dev-server on 4200) and the `serve-static` profile (Caddy reverse proxy for the production build, also defaulting to 4200) cannot run together. `up all` expanded to "every profile" without taking that conflict into account. After this PR, `./infra/local/dev.sh up all` brings up the comprehensive dev stack — infra + `dbtools` + `observability` + `apps` — and `serve-static` stays available via the explicit `./infra/local/dev.sh up serve-static` invocation when a developer actually wants to test a production build. ## Root cause `dev.compose.yml` publishes port 4200 in two services: - `portal-shell` (profile `apps`): `${SHELL_PORT:-4200}:4200` — Angular dev-server. - `serve-static` (profile `serve-static`): `${SERVE_STATIC_PORT:-4200}:4200` — Caddy serving the production build. `dev.sh`'s `ALL_PROFILES` array was used both as: 1. the teardown / status / logs scope (so a manually-started profile is still reachable for `down` and friends), **and** 2. the expansion target for `up all`. Conflating the two meant `up all` always tried to start `serve-static` even when `apps` was in scope — and the Docker port-publishing collision aborted the whole `up`. ## Fix Split the two concerns: ```bash # Every profile that exists — teardown / status / logs scope. ALL_PROFILES=(dbtools observability serve-static apps) # What `up all` expands to — serve-static excluded. UP_ALL_PROFILES=(dbtools observability apps) ``` `serve-static` stays accessible: - via explicit `dev.sh up serve-static` (the original way), - via `dev.sh down` / `status` / `logs` (still in `ALL_PROFILES`). Why exclude `serve-static` from `up all` rather than `apps`: - `apps` is the new "no native toolchain" dev mode (ADR-0030) — it _is_ what a comprehensive dev `up` should boot. - `serve-static` has zero value without a prior `nx build --configuration=production` (Caddy serves an empty `dist/` → 404 everywhere). Auto-starting it in `up all` would put a 404-machine in the stack by default. - The port number can stay at the Angular convention (4200) for the dev-server, which matches the devcontainer's `forwardPorts`. ## What lands | File | Change | | --- | --- | | `infra/local/dev.sh` | Split `ALL_PROFILES` (teardown scope) and `UP_ALL_PROFILES` (`up all` scope). Inline comment explains the exclusion of `serve-static`. Usage text updated. | | `infra/README.md` | Cheat-sheet row for `up all` clarifies the new behaviour. | ## Out of scope The script is **environment-agnostic** — it works identically when invoked on the local workstation or on `vm-dev`. Port publishing is on `0.0.0.0` by default, so services are reachable from a remote browser via the VM IP without any script change. The user-visible difference is only the URL host (`localhost:4200` locally vs `<vm-ip>:4200` from the workstation against the VM). No local-vs-vm mode in the script. ## Test plan - [x] `bash -n infra/local/dev.sh` passes. - [x] `./infra/local/dev.sh help` shows the updated `up all` description. - [ ] **On vm-dev**: `./infra/local/dev.sh up all` brings up postgres / redis / otel-collector / pgweb / jaeger / apps-deps (exits 0) / portal-bff / portal-shell / portal-admin without port conflicts; `serve-static` is **not** started. - [ ] `./infra/local/dev.sh up serve-static` (explicit) still starts Caddy on 4200, provided `apps` is **not** already up. - [ ] `./infra/local/dev.sh down` and `status` still see serve-static if it was started manually (ALL_PROFILES retains it). ## Related - Surfaced by the ADR-0030 dockerised dev mode VM validation — `up all` was added to the user-facing surface in that PR; this PR finishes wiring it. - The port collision was flagged as a caveat in the ADR-0030 PR body ("don't run `apps` and `serve-static` together"). This PR turns the caveat into a script invariant instead of relying on the user to remember.
julien added 1 commit 2026-06-01 13:04:48 +02:00
fix(infra): exclude serve-static from 'dev.sh up all' (port collision with apps)
CI / scan (pull_request) Successful in 4m44s
CI / commits (pull_request) Successful in 4m58s
CI / check (pull_request) Successful in 5m15s
CI / a11y (pull_request) Successful in 3m53s
CI / perf (pull_request) Successful in 8m14s
2a8f875a9c
dev.sh up all failed at startup with 'port 4200 already allocated':
both the apps profile (portal-shell dev-server, ADR-0030) and the
serve-static profile (Caddy reverse proxy) publish 4200 by default.

Split ALL_PROFILES (teardown / status / logs scope, unchanged) from
a new UP_ALL_PROFILES (what 'up all' expands to). serve-static drops
out of up all because:
- it collides with apps on 4200, and
- it has zero value without a prior nx build --configuration=production
  (otherwise Caddy 404s every request).

serve-static stays explicit: ./infra/local/dev.sh up serve-static.
Teardown still catches it via ALL_PROFILES.

Usage text + infra/README.md cheat-sheet updated.

The script is environment-agnostic — works the same on local and on
vm-dev. No local-vs-vm mode needed.
julien merged commit 045ff924a8 into main 2026-06-01 13:07:09 +02:00
julien deleted branch fix/dev-sh-up-all-include-apps 2026-06-01 13:07:11 +02:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: julien/apf_portal#261