Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion deploy/compose/Caddyfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
{$BUZZ_DOMAIN} {
encode zstd gzip

reverse_proxy relay:3000
# Device-pairing sidecar (compose.pair.yml). If the pairing overlay is
# disabled, requests to /pair fail with 502 instead of reaching the relay.
handle /pair {
reverse_proxy pair-relay:5000
}

handle {
reverse_proxy relay:3000
}
}
25 changes: 25 additions & 0 deletions deploy/compose/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,31 @@ keypair.
`.env`; use the Helm chart or a custom Compose configuration for providers
such as new Railway Storage Buckets that require `virtual` addressing.

## Device pairing

Mobile QR pairing (NIP-AB) needs the `buzz-pair-relay` sidecar: a
membership-gated (NIP-43) relay rejects unpaired devices, so the pairing
handshake runs through a separate ephemeral relay instead. Without it, phones
scanning the desktop QR fail with a WebSocket 404 on `<relay>/pair`.

The TLS stack includes the sidecar by default (`compose.pair.yml`):

- Runs `buzz-pair-relay` from the same relay image.
- Caddy routes `/pair` to it; everything else still goes to the relay.
- Sets `BUZZ_PAIRING_RELAY_URL=wss://$BUZZ_DOMAIN/pair` on the relay so the
pairing URL is advertised in NIP-11.

Set `BUZZ_COMPOSE_PAIRING=false` to opt out — `/pair` then returns 502 from
Caddy. Pairing is not wired for the non-TLS stack: there is no reverse proxy
to route `/pair`, and iOS requires `wss://` anyway.

Verify after `./run.sh start`:

```bash
curl -fsS "https://<your-domain>" -H 'Accept: application/nostr+json' | grep -o 'pairing_relay_url[^,]*'
curl -is "https://<your-domain>/pair" | head -1 # expect HTTP 400 (non-WebSocket request rejected)
```

Run `./run.sh backup-hint` for the backup checklist.

## Validation
Expand Down
29 changes: 29 additions & 0 deletions deploy/compose/compose.pair.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Device-pairing sidecar (NIP-AB) overlay. Included automatically by run.sh
# when BUZZ_COMPOSE_TLS=true (opt out with BUZZ_COMPOSE_PAIRING=false).
# Pairing requires the Caddy overlay: the phone connects over wss:// and the
# Caddyfile routes /pair to this service.
services:
relay:
environment:
# Advertised in the relay's NIP-11 document so clients connect here
# directly instead of guessing the legacy <relay>/pair path.
BUZZ_PAIRING_RELAY_URL: wss://${BUZZ_DOMAIN:?set BUZZ_DOMAIN}/pair

pair-relay:
image: ${BUZZ_IMAGE:-ghcr.io/block/buzz:main}
# The image ENTRYPOINT is buzz-relay; entrypoint (not command) is required
# to run the sidecar binary instead.
entrypoint: ["/usr/local/bin/buzz-pair-relay"]
environment:
BUZZ_PAIR_RELAY_BIND_ADDR: 0.0.0.0:5000
# TCP connect probe over /dev/tcp because the runtime image has bash but
# no curl/wget/socat (same approach as the relay healthcheck).
healthcheck:
test: ["CMD-SHELL", "bash -ec 'exec 3<>/dev/tcp/127.0.0.1/5000'"]
interval: 10s
timeout: 3s
retries: 12
start_period: 5s
restart: unless-stopped
networks:
- buzz-net
9 changes: 7 additions & 2 deletions deploy/compose/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ cd "${SCRIPT_DIR}"
COMPOSE_FILES=(-f compose.yml)
if [[ "${BUZZ_COMPOSE_TLS:-false}" == "true" ]]; then
COMPOSE_FILES+=(-f compose.caddy.yml)
if [[ "${BUZZ_COMPOSE_PAIRING:-true}" == "true" ]]; then
COMPOSE_FILES+=(-f compose.pair.yml)
fi
fi
if [[ "${BUZZ_COMPOSE_DEV:-false}" == "true" ]]; then
COMPOSE_FILES+=(-f compose.dev.yml)
Expand Down Expand Up @@ -121,8 +124,10 @@ Commands:
roster event. Do not use parallel adds (e.g. xargs -P).

Environment switches:
BUZZ_COMPOSE_TLS=true Include compose.caddy.yml for automatic HTTPS
BUZZ_COMPOSE_DEV=true Include compose.dev.yml for local admin ports/tools
BUZZ_COMPOSE_TLS=true Include compose.caddy.yml for automatic HTTPS
BUZZ_COMPOSE_DEV=true Include compose.dev.yml for local admin ports/tools
BUZZ_COMPOSE_PAIRING=false Disable the device-pairing sidecar
(compose.pair.yml, included by default with TLS)
MSG
;;
*)
Expand Down