Skip to content

fix(dev): make local service host ports configurable - #5615

Open
smkthat wants to merge 3 commits into
block:mainfrom
smkthat:smkthat/configurable-dev-service-ports
Open

smkthat wants to merge 3 commits into
block:mainfrom
smkthat:smkthat/configurable-dev-service-ports

Conversation

@smkthat

@smkthat smkthat commented Aug 12, 2026

Copy link
Copy Markdown

Summary

Local setup currently publishes fixed Docker host ports while application URLs
come from .env. Changing DATABASE_URL or REDIS_URL therefore leaves
Compose on the old port and can make migrations time out against the wrong
endpoint.

This change:

  • makes every development service host port configurable through .env, while
    preserving the current defaults and 127.0.0.1 bindings;
  • keeps container-side ports fixed and leaves service credentials unchanged;
  • loads and validates service settings during setup, with a fail-fast check
    when a loopback URL disagrees with its mapped port;
  • makes the relay-test launcher resolve the ports actually published by local
    Compose while pinning database, Redis, and MinIO endpoints and credentials to
    the development stack, so values from .env cannot redirect schema changes
    to an external service;
  • always reconciles Compose before health checks so edits to .env take effect
    even when the existing Postgres and Redis containers are healthy;
  • documents the variables and adds a regression test for default/custom
    mappings, credential isolation, URL validation, Compose reconciliation, and
    external-endpoint protection in the relay-test launcher.

Related issue

Fixes #2479.

Related work:

Compared with the open alternatives, this PR keeps the scope limited to local
service configuration while covering all published Compose ports and the
setup/test call sites that consume them.

Testing

  • ./scripts/test-dev-service-ports.sh
  • bash -n scripts/dev-setup.sh scripts/start-relay-for-tests.sh scripts/lib/dev-service-env.sh scripts/test-dev-service-ports.sh
  • shellcheck scripts/dev-setup.sh scripts/start-relay-for-tests.sh scripts/lib/dev-service-env.sh scripts/test-dev-service-ports.sh
  • docker compose --env-file .env.example config --quiet
  • docker compose config --quiet with custom local Postgres, Redis, and MinIO ports
  • just setup with those custom ports (Compose reconciliation, migrations,
    seed, dependency setup, and hooks all succeeded)
  • just test-unit
  • just ci (formatting, linting, builds, and all Rust, desktop, web, and mobile
    test suites, including 4,715 desktop, 2,402 Tauri, and 1,261 mobile tests)
  • pre-push hook, including branch-skew validation

No UI changes; screenshots are not applicable.

@smkthat
smkthat force-pushed the smkthat/configurable-dev-service-ports branch from 34919b7 to b946ef5 Compare August 12, 2026 00:42
@smkthat
smkthat marked this pull request as ready for review August 12, 2026 01:39
@smkthat
smkthat requested a review from a team as a code owner August 12, 2026 01:39
@ravarora2

Copy link
Copy Markdown
Contributor

🤖 Tested locally — LGTM. ✅

Checked out the branch in an isolated worktree and ran the non-destructive checks (no containers started, DB/Desktop untouched):

  • bash -n on all four changed scripts — clean.
  • ./scripts/test-dev-service-ports.shpasses (Dev service port checks passed, exit 0). This covers default/custom port rendering, credential isolation, local-URL/port validation (without leaking passwords), the remote-endpoint protection in the relay-test launcher, and Compose reconciliation.
  • Independent docker compose config render:
    • Defaults unchanged, every service still bound to 127.0.0.1.
    • PGPORT=15432 / MINIO_CONSOLE_PORT=9002 move only the host port; container ports stay fixed.
    • Injecting POSTGRES_PASSWORD=HACKED / BUZZ_S3_SECRET_KEY=HACKED via env did not change the rendered credentials — they stay buzz_dev/buzz_dev_secret. Credential isolation holds.

Nice touch pinning the test-relay launcher's host + credentials to the local dev stack and only borrowing the port from Compose, so a developer's remote DATABASE_URL/PG* can't become an auto-approved schema target — and there's a regression test proving it.

A few non-blocking notes:

  1. validate_env now shells out to node at just setup time — worth confirming node is guaranteed on PATH there (it is via hermit in my run).
  2. Changing PGPORT/etc. will break a concurrently-running Desktop, since the dev Compose uses fixed container names and Desktop expects the standard ports. TESTING.md mentions the shared stack; a one-liner that a port override affects Desktop too could save someone a confusing debugging session.
  3. Minor: a portless BUZZ_S3_ENDPOINT (e.g. http://localhost) validates against default port 80 and would fail against MINIO_API_PORT=9000. Fine for the common case, just noting the edge.

(I only ran the static/rendered tier; I didn't start containers on a custom port since that shares the local Docker stack.)

@ravarora2 ravarora2 added the triage-ready Appropriate for agentic review label Aug 13, 2026
@smkthat

smkthat commented Aug 15, 2026

Copy link
Copy Markdown
Author

@ravarora2 Thanks for the thorough review and the LGTM. I addressed two small follow-ups from your non-blocking notes:

  • scripts/dev-setup.sh now prepends <repo>/bin to PATH before validate_env. A new regression case runs dev-setup.sh without a system Node binary and verifies that it uses the Hermit shim before reaching the Compose step.
  • TESTING.md now explicitly notes that changing a host-port override reconciles the shared Compose stack, so a running Desktop or relay using the previous ports will lose its service connections.

I intentionally kept a portless BUZZ_S3_ENDPOINT=http://localhost fail-closed: it means :80 and should not implicitly assume the configured MinIO port.

Verified with ./scripts/test-dev-service-ports.sh, shell syntax checks, and just ci.

@smkthat
smkthat force-pushed the smkthat/configurable-dev-service-ports branch from 5d3c564 to dd2a8c8 Compare August 15, 2026 01:05
smkthat and others added 3 commits August 17, 2026 13:09
Signed-off-by: Mikhail Vlasenko <ya@smkthat.ru>
Signed-off-by: Mikhail Vlasenko <ya@smkthat.ru>
Canonicalize loopback aliases before comparing configured service ports, reject unspecified bind addresses, and cover the setup boundary before Compose or migrations can run.

Co-authored-by: Ravneet Arora <rarora@squareup.com>
Signed-off-by: Ravneet Arora <rarora@squareup.com>
@ravarora2
ravarora2 force-pushed the smkthat/configurable-dev-service-ports branch from dd2a8c8 to ac7abeb Compare August 17, 2026 17:12
@ravarora2

Copy link
Copy Markdown
Contributor

🤖 Follow-up change summary after the review blocker was fixed:

What changed

  • Rebased this branch onto current main.
  • Reworked the local-service URL validation so it recognizes equivalent loopback destinations instead of comparing only three literal host strings. This now covers trailing-dot localhost, the full IPv4 loopback range (including shorthand and integer forms), IPv6 loopback, and IPv4-mapped IPv6 loopback.
  • Unspecified bind addresses such as 0.0.0.0 and [::] now fail closed instead of being treated as safe remote endpoints.
  • The configured URL port is compared with the Compose host port for every local/loopback form, preventing setup from starting Buzz PostgreSQL on one port and migrating a different local database on another port.
  • Added the expanded hostname/port matrix plus a setup-level regression test proving that a mismatch stops before either docker compose up or buzz-admin migrate is invoked.

Verification

  • Final pushed head: ac7abeb5bbc55ab92d52cca0c71ab9fc6b0163ee.
  • The focused port regression test passed at that head.
  • Full just ci passed during the fix validation.
  • A final full cargo test -p buzz-acp rerun passed: 778 library tests and 9 integration tests. The first run had one known timing-sensitive keepalive failure; the clean full rerun passed without code changes.
  • git diff --check, formatting, clippy, DCO trailers, and clean-worktree checks passed.

The configurable-port design remains unchanged; this commit hardens only the local-address safety boundary and its regression coverage.

@ravarora2 ravarora2 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm.Let's wait for owners to have a final review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

triage-ready Appropriate for agentic review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

dev setup: allow Postgres and Redis host ports to be configured

2 participants