Files
Khalid Abdi f10d01546b feat(backend): public relay for off-network wallet scanning
Scan-to-connect only worked on the same Wi-Fi because the QR carried a LAN
relay URL. Give the relay a public address two ways:

- `npm run dev:tunnel` (scripts/dev-tunnel.mjs) opens a cloudflared tunnel
  to localhost:4000 and starts the backend with PUBLIC_RELAY_URL set to the
  public https URL, so the QR carries it and a phone on any network connects.
- Deploy configs for Fly.io (fly.toml), Render (render.yaml), and Railway
  (railway.json), all building the existing Dockerfile.

Also harden resolveRelayUrl to honor x-forwarded-proto so the derived QR URL
is https behind a TLS proxy (iOS ATS requires wss).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 20:01:54 +03:00

50 lines
1.7 KiB
TOML

# Fly.io deploy for the temetro backend + wallet relay (deploys ./Dockerfile).
#
# One-time setup (run from backend/):
# fly launch --no-deploy --copy-config # keep this file; pick your app name + region
# fly volumes create temetro_data --size 1 # persists auto-generated secrets + uploads
# fly postgres create # then:
# fly postgres attach <postgres-app-name> # sets DATABASE_URL secret
# fly secrets set \
# PUBLIC_RELAY_URL=https://<app>.fly.dev \ # baked into the wallet-import QR (must be public https)
# BETTER_AUTH_URL=https://<app>.fly.dev \ # https → secure auth cookies
# FRONTEND_URL=https://<your-frontend-origin>
# fly deploy
#
# Any other Docker host (Render/Railway/VPS) works with the same env contract;
# Fly is just the concrete example.
app = "temetro-backend" # change to your Fly app name
primary_region = "iad"
[build]
dockerfile = "Dockerfile"
[env]
NODE_ENV = "production"
PORT = "4000"
UPLOAD_DIR = "/var/lib/temetro/uploads"
# Persists the entrypoint's auto-generated secrets (/var/lib/temetro) and
# uploaded files across deploys. Skip this only if you set BETTER_AUTH_SECRET /
# AI_CREDENTIALS_KEY as fly secrets instead.
[mounts]
source = "temetro_data"
destination = "/var/lib/temetro"
[http_service]
internal_port = 4000
force_https = true
# Keep one machine always up — the wallet relay holds live WebSocket
# connections, so the app should not sleep mid-pairing.
auto_stop_machines = "off"
auto_start_machines = true
min_machines_running = 1
[[http_service.checks]]
method = "get"
path = "/health"
interval = "15s"
timeout = "2s"
grace_period = "10s"