Skip to content

feat(deploy): add device-pairing sidecar to the compose stack - #4656

Open
vishoo7 wants to merge 1 commit into
block:mainfrom
vishoo7:compose-pairing-sidecar
Open

feat(deploy): add device-pairing sidecar to the compose stack#4656
vishoo7 wants to merge 1 commit into
block:mainfrom
vishoo7:compose-pairing-sidecar

Conversation

@vishoo7

@vishoo7 vishoo7 commented Aug 4, 2026

Copy link
Copy Markdown

Problem

Mobile QR pairing fails out of the box for deploy/compose deployments. A membership-gated (NIP-43) relay can't accept unpaired devices, so the desktop app falls back to pointing the phone at the legacy <relay>/pair path (resolve_pairing_relay_url in desktop/src-tauri/src/commands/pairing.rs). The compose stack never runs the buzz-pair-relay sidecar or routes /pair, so the phone's WebSocket upgrade lands on the main relay's router and pairing always dies with "websocket connection failed: http error: 404 not found".

The Helm chart already handles this (pairingRelay.enabled runs the sidecar from the relay image and advertises it in NIP-11); this PR brings the compose bundle to parity.

Changes

  • compose.pair.yml (new overlay): runs /usr/local/bin/buzz-pair-relay from the existing relay image via an entrypoint: override (the image ENTRYPOINT is buzz-relay, so command: alone would silently start a second main relay), binds 0.0.0.0:5000, and adds a bash /dev/tcp healthcheck matching the relay's approach. It also sets BUZZ_PAIRING_RELAY_URL=wss://$BUZZ_DOMAIN/pair on the relay so clients get the pairing URL from NIP-11 instead of relying on the legacy path fallback.
  • Caddyfile: exclusive handle blocks — /pairpair-relay:5000, everything else → relay:3000.
  • run.sh: includes the overlay by default when BUZZ_COMPOSE_TLS=true; BUZZ_COMPOSE_PAIRING=false opts out. Not wired for the non-TLS stack (no reverse proxy to route /pair, and iOS requires wss://).
  • README.md: new "Device pairing" section with verification steps.

Testing

  • docker compose -f compose.yml -f compose.caddy.yml -f compose.pair.yml config renders the merged stack correctly (sidecar entrypoint/env/healthcheck, relay BUZZ_PAIRING_RELAY_URL).
  • Verified end-to-end on a live single-node VPS deployment of this stack: NIP-11 advertises pairing_relay_url, GET /pair returns the sidecar's 400 for non-WebSocket requests (previously the relay's 404), and iOS QR pairing against the desktop app completes through SAS confirmation.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Voret84oXtBS5hfRo66uGS

Mobile QR pairing was broken out of the box for compose deployments: a
membership-gated (NIP-43) relay makes the desktop app point the phone at
the legacy <relay>/pair fallback, but the compose stack never ran the
buzz-pair-relay sidecar or routed /pair, so pairing always failed with a
WebSocket 404. The Helm chart already supports this via
pairingRelay.enabled; this brings the compose bundle to parity.

- compose.pair.yml runs buzz-pair-relay from the existing relay image
  (entrypoint override — the image ENTRYPOINT is buzz-relay) and sets
  BUZZ_PAIRING_RELAY_URL so the relay advertises the pairing URL in
  NIP-11 instead of relying on the legacy path fallback.
- Caddyfile routes /pair to the sidecar via exclusive handle blocks.
- run.sh includes the overlay by default with BUZZ_COMPOSE_TLS=true;
  BUZZ_COMPOSE_PAIRING=false opts out.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Voret84oXtBS5hfRo66uGS
Signed-off-by: vishoo7 <19656433+vishoo7@users.noreply.github.com>
@vishoo7
vishoo7 requested a review from a team as a code owner August 4, 2026 03:42
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.

2 participants