dev compose: wire key master + nsec bunker integration, CORS allowlist, transport roster gate
LNbits now fail-closes at boot without LNBITS_KEY_MASTER (aiolabs/lnbits#9 PR #17), and account provisioning routes through the nsec bunker (aiolabs/lnbits#18 phase 2.1+2.2) when LNBITS_NSEC_BUNKER_* are set, so both wiring blocks are required for the dev stack to boot and serve a webapp signup. Also covers: - LNBITS_CORS_ALLOWED_ORIGINS for the standalone webapp dev ports (aiolabs/lnbits PR #31; standalone hubs 5173 + 5180-5187 across the three browser-distinct origins localhost / 192.168.0.32 / 127.0.0.1). - NOSTR_TRANSPORT_ROSTER_REQUIRED to reject kind-21000 RPCs from unregistered senders rather than the silent-drop-via-auto-create failure mode caught 2026-05-30 (aiolabs/lnbits#42, satmachineadmin#20). - Bunker reliability: restart=unless-stopped so the watchdog's clean exit(0) on prolonged relay-disconnect gets auto-recovered, plus NSEC_BUNKER_DISABLE_WATCHDOG=1 to keep the bunker idling patiently through lnbits rebuilds longer than the 60s grace window, and NSEC_BUNKER_AUTOUNLOCK_PASSPHRASE so RemoteBunkerSigner clients don't need to drive a per-restart unlock_key RPC (aiolabs/nsecbunkerd#16). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
07532a0d95
commit
c3c531f1f3
1 changed files with 73 additions and 1 deletions
|
|
@ -45,6 +45,47 @@ services:
|
||||||
NOSTR_TRANSPORT_RELAYS: '["ws://localhost:5001/nostrrelay/test"]'
|
NOSTR_TRANSPORT_RELAYS: '["ws://localhost:5001/nostrrelay/test"]'
|
||||||
NOSTR_TRANSPORT_PRIVATE_KEY: ${NOSTR_TRANSPORT_PRIVATE_KEY}
|
NOSTR_TRANSPORT_PRIVATE_KEY: ${NOSTR_TRANSPORT_PRIVATE_KEY}
|
||||||
NOSTR_TRANSPORT_PUBLIC_KEY: ${NOSTR_TRANSPORT_PUBLIC_KEY}
|
NOSTR_TRANSPORT_PUBLIC_KEY: ${NOSTR_TRANSPORT_PUBLIC_KEY}
|
||||||
|
# Path-B roster gate (aiolabs/lnbits#42 / satmachineadmin#20). When
|
||||||
|
# true, inbound kind-21000 RPCs from unregistered sender pubkeys are
|
||||||
|
# rejected + ERROR-logged instead of auto-creating an account-from-
|
||||||
|
# npub (which was the silent-drop failure mode on 2026-05-30).
|
||||||
|
# satmachineadmin's resolver routes registered ATMs to the operator's
|
||||||
|
# wallet directly; under this flag, that's the ONLY routing path.
|
||||||
|
NOSTR_TRANSPORT_ROSTER_REQUIRED: "true"
|
||||||
|
# Envelope-encryption master key for user nostr nsecs (aiolabs/lnbits#9
|
||||||
|
# PR #17). Required — lnbits fail-closes at startup if unset. Sourced
|
||||||
|
# from .env; rotate via `openssl rand -hex 32` (one-time ops procedure).
|
||||||
|
LNBITS_KEY_MASTER: ${LNBITS_KEY_MASTER}
|
||||||
|
|
||||||
|
# nsec bunker integration (aiolabs/lnbits#18 phase 2.1 + 2.2).
|
||||||
|
# When set, new accounts get provisioned via the sidecar bunker
|
||||||
|
# (signer_type=RemoteBunkerSigner) instead of the LocalSigner
|
||||||
|
# encrypted-blob path. All four must be present together or
|
||||||
|
# NsecBunkerAdminClient.from_settings raises.
|
||||||
|
# Bunker container needs NSECBUNKER_ADMIN_NPUBS configured with the
|
||||||
|
# npub corresponding to LNBITS_NSEC_BUNKER_ADMIN_NSEC below.
|
||||||
|
LNBITS_NSEC_BUNKER_URL: ${LNBITS_NSEC_BUNKER_URL:-}
|
||||||
|
LNBITS_NSEC_BUNKER_PUBKEY: ${LNBITS_NSEC_BUNKER_PUBKEY:-}
|
||||||
|
LNBITS_NSEC_BUNKER_ADMIN_NSEC: ${LNBITS_NSEC_BUNKER_ADMIN_NSEC:-}
|
||||||
|
LNBITS_NSEC_BUNKER_KEYSTORE_PASSPHRASE: ${LNBITS_NSEC_BUNKER_KEYSTORE_PASSPHRASE:-}
|
||||||
|
# CORS allowlist for credentialed cross-origin webapp calls
|
||||||
|
# (aiolabs/lnbits PR #31). Mirrors the aio-demo wiring from
|
||||||
|
# server-deploy `b920b79`; covers three hostname flavors browsers
|
||||||
|
# treat as distinct origins: `localhost`, the LAN IP `192.168.0.32`,
|
||||||
|
# and the loopback IP `127.0.0.1` (browsers do NOT alias loopback
|
||||||
|
# to localhost for SOP purposes — `localhost` and `127.0.0.1` are
|
||||||
|
# different origins as far as CORS is concerned; gotcha caught
|
||||||
|
# 2026-05-30T11:05Z when a chromium session opened on the loopback
|
||||||
|
# IP got rejected against an allowlist that only had localhost +
|
||||||
|
# LAN-IP). Covers every standalone webapp dev port from
|
||||||
|
# `~/dev/webapp/dev/vite.*.config.ts` plus the umbrella 5173:
|
||||||
|
# 5173 main, 5180 libra, 5181 activities, 5182 wallet,
|
||||||
|
# 5183 chat, 5184 forum, 5185 market, 5186 tasks,
|
||||||
|
# 5187 restaurant.
|
||||||
|
# Empty allowlist would fall back to `Access-Control-Allow-Origin: *`
|
||||||
|
# (no credentials); explicit allowlist also covers the
|
||||||
|
# /auth/sign-event credentialed flow when bucket-B PRs land.
|
||||||
|
LNBITS_CORS_ALLOWED_ORIGINS: '["http://localhost:5173","http://192.168.0.32:5173","http://127.0.0.1:5173","http://localhost:5180","http://192.168.0.32:5180","http://127.0.0.1:5180","http://localhost:5181","http://192.168.0.32:5181","http://127.0.0.1:5181","http://localhost:5182","http://192.168.0.32:5182","http://127.0.0.1:5182","http://localhost:5183","http://192.168.0.32:5183","http://127.0.0.1:5183","http://localhost:5184","http://192.168.0.32:5184","http://127.0.0.1:5184","http://localhost:5185","http://192.168.0.32:5185","http://127.0.0.1:5185","http://localhost:5186","http://192.168.0.32:5186","http://127.0.0.1:5186","http://localhost:5187","http://192.168.0.32:5187","http://127.0.0.1:5187"]'
|
||||||
# Lowered from the 40_000 default just to make sharding easy to
|
# Lowered from the 40_000 default just to make sharding easy to
|
||||||
# exercise in local tests without seeding hundreds of payments.
|
# exercise in local tests without seeding hundreds of payments.
|
||||||
# Production runs should leave this unset (defaults to 40_000).
|
# Production runs should leave this unset (defaults to 40_000).
|
||||||
|
|
@ -124,7 +165,17 @@ services:
|
||||||
# nsecbunkerd dev branch and ~/dev/coordination/log.md 2026-05-27.
|
# nsecbunkerd dev branch and ~/dev/coordination/log.md 2026-05-27.
|
||||||
build: ${NSECBUNKER_SRC:-/home/padreug/dev/nsecbunkerd/dev}
|
build: ${NSECBUNKER_SRC:-/home/padreug/dev/nsecbunkerd/dev}
|
||||||
hostname: nsecbunker
|
hostname: nsecbunker
|
||||||
restart: on-failure
|
# Use `unless-stopped` (not `on-failure`) so the watchdog's deliberate
|
||||||
|
# exit(0) on prolonged relay-disconnect gets auto-recovered. The
|
||||||
|
# bunker's relay-watchdog is designed to exit-and-let-supervisor-
|
||||||
|
# restart; `on-failure` is half-implementing that contract (catches
|
||||||
|
# crashes but not the clean exit-as-restart-signal). See the watchdog
|
||||||
|
# comment in src/daemon/admin/index.ts and the routine-rebuild
|
||||||
|
# gotcha: any restart of the lnbits container that takes >60s knocks
|
||||||
|
# the bunker's WebSocket out beyond the grace window, which under
|
||||||
|
# `on-failure` left the bunker silently dead after every
|
||||||
|
# `regtest-lnbits-rebuild` until manually started.
|
||||||
|
restart: unless-stopped
|
||||||
pids_limit: 100
|
pids_limit: 100
|
||||||
mem_limit: 256mb
|
mem_limit: 256mb
|
||||||
memswap_limit: 256mb
|
memswap_limit: 256mb
|
||||||
|
|
@ -135,6 +186,27 @@ services:
|
||||||
# Set to '1' in .env or shell to enable REQUEST_IN / RESPONSE_SENT /
|
# Set to '1' in .env or shell to enable REQUEST_IN / RESPONSE_SENT /
|
||||||
# PUBLISHED / PUBLISH_FAILED instrumentation. Default off.
|
# PUBLISHED / PUBLISH_FAILED instrumentation. Default off.
|
||||||
NSEC_BUNKER_DEBUG_TRANSPORT: ${NSEC_BUNKER_DEBUG_TRANSPORT:-0}
|
NSEC_BUNKER_DEBUG_TRANSPORT: ${NSEC_BUNKER_DEBUG_TRANSPORT:-0}
|
||||||
|
# Disable the relay-connection watchdog in the regtest stack.
|
||||||
|
# The watchdog calls process.exit(0) if the relay pool reports
|
||||||
|
# no connected relays for >60s; in dev that fires routinely
|
||||||
|
# during lnbits rebuilds (regtest-lnbits-rebuild takes more
|
||||||
|
# than 60s, the bunker's WebSocket drops, watchdog exits the
|
||||||
|
# process). With this set to '1' the bunker idles patiently
|
||||||
|
# instead — NDK's relay-reconnect loop attaches once lnbits is
|
||||||
|
# back up, and the in-memory unlocked-keys state from autounlock
|
||||||
|
# persists across the disconnect. Production deployments should
|
||||||
|
# leave this unset so external liveness checking gets the
|
||||||
|
# exit-as-restart-signal it expects.
|
||||||
|
NSEC_BUNKER_DISABLE_WATCHDOG: "1"
|
||||||
|
# Boot-time autounlock per aiolabs/nsecbunkerd#16 — every encrypted
|
||||||
|
# key in the Key table is unlocked at startup using this passphrase
|
||||||
|
# so RemoteBunkerSigner clients (lnbits, future webapp NIP-46) don't
|
||||||
|
# need to drive an admin unlock_key RPC per restart. Same passphrase
|
||||||
|
# the operator-side LNBITS_NSEC_BUNKER_KEYSTORE_PASSPHRASE uses to
|
||||||
|
# provision keys. See docs/AUTOUNLOCK.md in the bunker repo for the
|
||||||
|
# security trade. Leave unset to keep autounlock off (manual unlock
|
||||||
|
# per key per restart, the pre-#16 default).
|
||||||
|
NSEC_BUNKER_AUTOUNLOCK_PASSPHRASE: ${LNBITS_NSEC_BUNKER_KEYSTORE_PASSPHRASE:-}
|
||||||
volumes:
|
volumes:
|
||||||
- ./data/nsecbunker:/app/config
|
- ./data/nsecbunker:/app/config
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue