Skip to content

deploy/compose is missing two pieces the Helm chart has: desktop clients can't connect, and mobile pairing 404s #3291

Description

@sandeepgoenka

Standing up a fresh single-node relay by following deploy/compose/README.md produces a relay that the official desktop app cannot join, and whose "Pair Mobile Device" flow always fails. Both are gaps between deploy/compose and deploy/charts/buzz, and both surface as misleading errors that point away from the real cause.

Relay image: ghcr.io/block/buzz:sha-3a4bf51. Deployment: deploy/compose with BUZZ_COMPOSE_TLS=true, unmodified .env.example values except secrets and domain.


1. .env.example omits the desktop app's origin from BUZZ_CORS_ORIGINS

deploy/compose/.env.example sets:

BUZZ_CORS_ORIGINS=https://buzz.example.com

The Tauri desktop app's webview origin is tauri://localhost, so every REST call it makes is blocked by the browser. AddCommunityDialog → "Join an existing community" fails with "Load failed" — WebKit's generic fetch error. No WebSocket is ever opened, so the relay logs show zero connection attempts, which makes it look like an auth or network problem rather than CORS.

Reproduce against a relay deployed from the bundle:

# Allowed origin — header present
curl -sD- -o /dev/null -H "Origin: https://relay.example.com" \
  https://relay.example.com/api/join-policy | grep -i access-control-allow-origin
# access-control-allow-origin: https://relay.example.com

# Desktop app's actual origin — no header, browser blocks the response
curl -sD- -o /dev/null -H "Origin: tauri://localhost" \
  https://relay.example.com/api/join-policy | grep -i access-control-allow-origin
# (nothing)

crates/buzz-relay/src/config.rs already documents tauri://localhost as the expected value, so this looks like the example file simply drifted from the code comment.

Suggested fix — add the app origins to .env.example:

BUZZ_CORS_ORIGINS=https://buzz.example.com,tauri://localhost,http://tauri.localhost,https://tauri.localhost

2. The bundle advertises NIP-43 but ships no pairing sidecar, so /pair 404s

deploy/charts/buzz deploys buzz-pair-relay as its own workload (templates/pairing-relay.yaml) and wires BUZZ_PAIRING_RELAY_URL. deploy/compose has neither, but the main relay still advertises NIP-43 in its NIP-11 document.

desktop/src-tauri/src/commands/pairing.rs::resolve_pairing_relay_url keys off exactly that: with NIP-43 advertised and no pairing_relay_url present, it takes the LegacyPath branch and dials wss://<relay>/pair. The main relay has no such route, so pairing fails 100% of the time on a compose deployment:

curl -so /dev/null -w '%{http_code}\n' https://relay.example.com/pair
# 404

In the UI this renders as the QR code flashing on screen and immediately disappearing, with WebSocket connection failed: HTTP error: 404 Not Found.

Suggested fix — ship the sidecar in the compose bundle, the same way the chart does. A working local override, for reference:

# compose.pair.yml
services:
  pair-relay:
    image: ${BUZZ_IMAGE}
    entrypoint: ["/usr/local/bin/buzz-pair-relay"]   # image ENTRYPOINT is buzz-relay, so `command:` is silently ignored
    environment:
      BUZZ_PAIR_RELAY_BIND_ADDR: 0.0.0.0:5000
    restart: unless-stopped
    networks: [buzz-net]
{$BUZZ_DOMAIN} {
  encode zstd gzip
  @pair path /pair /pair/*
  reverse_proxy @pair pair-relay:5000
  reverse_proxy relay:3000
}

plus BUZZ_PAIRING_RELAY_URL=wss://<domain>/pair in .env so NIP-11 advertises it explicitly rather than relying on the legacy path convention. With that in place /pair returns 101 Switching Protocols and pairing completes normally.

One footgun worth a comment in the example: because the image's ENTRYPOINT is /usr/local/bin/buzz-relay, using command: to select the pairing binary silently starts a second main relay instead. It then contends for the Postgres pool and crash-loops, and the proxy returns 502 — an error that looks nothing like the actual mistake.


Happy to open a PR for either or both if that's useful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions