# Reverse proxy in front of RTL running in BTCPay Server's single-sign-on mode. # # Stands in for the traefik instance BTCPay puts in front of its bundled RTL. # The location regex mirrors the router rule BTCPay labels that container with: # # Host(`${BTCPAY_HOST}`) && (Path(`/rtl`) || PathPrefix(`/rtl/`)) # # so only /rtl and /rtl/* are proxied and everything else 404s here. That # strictness is deliberate: RTL is built with (angular.json) # and mounts every route under baseHref '/rtl' (server/utils/common.ts), so a # request that escapes the prefix is a bug the harness should surface rather # than quietly serve. # # The prefix is passed through unmodified -- there is no strip-prefix step to # get wrong, because RTL expects to see it. proxy_pass without a URI part # preserves the original request URI. map $http_upgrade $connection_upgrade { default upgrade; '' close; } server { listen 80; server_name _; location ~ ^/rtl(/|$) { proxy_pass http://rtl-sso:3000; # RTL runs with Express 'trust proxy' enabled, so these are what it sees # as the client address in its logs and rate limiting. proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # RTL's websocket lives at /rtl/api/ws and stays open for the life of the # session. Without the upgrade headers it fails the handshake and the UI # silently stops receiving live updates; without the long read timeout # nginx drops it after 60s. proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_read_timeout 3600s; } }