Networking
Scryer’s networking settings describe different sides of the same connection. Keeping those responsibilities separate makes direct, Docker, and reverse-proxy deployments much easier to reason about.
SCRYER_BINDcontrols the local address and port where the Scryer process accepts connections.SCRYER_PUBLIC_URLis the browser-facing origin that OAuth discovery advertises. It does not change where Scryer listens.SCRYER_BASE_PATHis the path prefix Scryer actually serves, such as/scryer.SCRYER_TLS_CERTandSCRYER_TLS_KEYenable direct HTTPS termination inside Scryer. Leave both unset when a reverse proxy terminates TLS.SCRYER_RATE_LIMIT_TRUSTED_PROXY_IPSidentifies the controlled proxy addresses allowed to supply client identity throughX-Forwarded-For.
The complete defaults and accepted values remain in the Configuration reference.
Choose A Deployment Shape
Section titled “Choose A Deployment Shape”Local Machine Only
Section titled “Local Machine Only”The native default listens only on loopback:
SCRYER_BIND=127.0.0.1:8080Only software on the same machine can connect. Open http://127.0.0.1:8080. Homebrew uses the same loopback-only shape on port 8686 unless you override it.
Direct LAN Access
Section titled “Direct LAN Access”Listen on all IPv4 interfaces when other trusted devices on the network need to connect directly:
SCRYER_BIND=0.0.0.0:8080SCRYER_AUTH_ENABLED=trueOpen http://<server-address>:8080 from another device. Restrict the port to the intended LAN or VPN with the host firewall. For IPv6, use a bracketed socket address such as [::]:8080.
Binding to a non-loopback address makes the service reachable; it does not authenticate clients or configure a firewall.
Reverse Proxy At The Site Root
Section titled “Reverse Proxy At The Site Root”For a public hostname, terminate HTTPS at the reverse proxy and keep the Scryer connection private to the host or container network:
SCRYER_BIND=0.0.0.0:8080SCRYER_AUTH_ENABLED=trueSCRYER_PUBLIC_URL=https://scryer.example.comSCRYER_RATE_LIMIT_TRUSTED_PROXY_IPS=172.20.0.2If the proxy runs on the same host as a native Scryer process, bind Scryer to 127.0.0.1 instead. If the proxy and Scryer run in separate containers, Scryer must listen on the container interface, normally 0.0.0.0, and both services should share a dedicated Docker network.
A minimal Caddy site is:
scryer.example.com { reverse_proxy scryer:8080}Caddy preserves the public Host, adds the usual forwarding headers, and proxies WebSocket upgrades by default.
Reverse Proxy Under A Path
Section titled “Reverse Proxy Under A Path”Set a base path when Scryer shares a hostname with another application:
SCRYER_BIND=0.0.0.0:8080SCRYER_AUTH_ENABLED=trueSCRYER_BASE_PATH=/scryerSCRYER_PUBLIC_URL=https://media.example.comSCRYER_RATE_LIMIT_TRUSTED_PROXY_IPS=172.20.0.2SCRYER_PUBLIC_URL is an origin only. Do not include /scryer in it. Scryer combines the public origin and base path when it advertises OAuth endpoints.
The proxy must preserve the prefix on the upstream request:
media.example.com { @scryer path /scryer /scryer/* reverse_proxy @scryer scryer:8080}Do not use a path-stripping rule. With this configuration, Scryer serves:
- UI:
/scryer/ - GraphQL:
/scryer/graphql - GraphQL WebSocket:
/scryer/graphql/ws - Health:
/scryer/health - Readiness:
/scryer/health/ready
A request to /scryer redirects to /scryer/ so browser asset paths resolve correctly.
Direct HTTPS Without A Reverse Proxy
Section titled “Direct HTTPS Without A Reverse Proxy”Scryer can terminate HTTPS itself when both PEM paths are available at startup:
SCRYER_BIND=0.0.0.0:8443SCRYER_TLS_CERT=/config/tls/fullchain.pemSCRYER_TLS_KEY=/config/tls/privkey.pemSCRYER_PUBLIC_URL=https://scryer.example.com:8443SCRYER_AUTH_ENABLED=trueBoth TLS variables are required together. The paths must be readable by the Scryer process, or startup fails. Certificates are loaded at startup, so restart Scryer after renewal.
For most container deployments, terminating TLS at a dedicated reverse proxy keeps certificate management in one place. Do not set the Scryer TLS variables in that topology.
Reverse Proxy Requirements
Section titled “Reverse Proxy Requirements”Any reverse proxy in front of Scryer must:
- Preserve the browser-facing
Hostheader. - Set
X-Forwarded-Prototo one exacthttporhttpsvalue. - Append the connecting client to
X-Forwarded-For. - Support WebSocket upgrades on
/graphql/ws, including the configured base path when present. - Preserve
SCRYER_BASE_PATHinstead of stripping it.
Scryer uses Host and X-Forwarded-Proto for same-origin WebSocket and OAuth behavior. Explicitly setting SCRYER_PUBLIC_URL is recommended behind a reverse proxy so OAuth metadata cannot advertise an internal hostname or HTTP scheme when headers are missing or rewritten.
Trusted Proxy Addresses
Section titled “Trusted Proxy Addresses”Forwarding headers are untrusted by default. Without SCRYER_RATE_LIMIT_TRUSTED_PROXY_IPS, every user behind a proxy shares the proxy’s rate-limit bucket.
Trust only the exact address or narrow CIDR used by proxies you control:
SCRYER_RATE_LIMIT_TRUSTED_PROXY_IPS=172.20.0.2Multiple values are comma-separated. Configure every controlled proxy hop that Scryer should remove from the right side of the chain. For rate-limit identity, Scryer uses only X-Forwarded-For; missing or malformed chains safely fall back to the socket peer.
This setting affects rate limiting only. It does not grant administrative access and does not make the proxy authoritative for WebAuthn, OAuth, or unauthenticated-access policy.
Passkeys And The Public Origin
Section titled “Passkeys And The Public Origin”Passkeys need an explicit, stable HTTPS origin in addition to the general networking settings:
SCRYER_WEBAUTHN_RP_ID=scryer.example.comSCRYER_WEBAUTHN_RP_ORIGIN=https://scryer.example.comSCRYER_WEBAUTHN_RP_NAME=ScryerThe relying-party ID is a hostname. The relying-party origin is the exact scheme, host, and optional port seen by the browser. Neither value includes SCRYER_BASE_PATH. See Login and passkey setup for the full authentication flow.
Container And Outbound Connectivity
Section titled “Container And Outbound Connectivity”Inbound browser traffic and Scryer’s outbound integration traffic use different addresses:
- A browser uses the host port or public reverse-proxy URL.
- Another Compose service uses the Scryer service name, such as
http://scryer:8080. - Scryer reaches another container by that service’s Compose name, such as
http://sabnzbd:8080. localhostinside the Scryer container means the Scryer container itself, not the Docker host and not another container.
Configure download clients, indexers, metadata providers, and other integration URLs in the Scryer UI using addresses reachable from the Scryer process. SCRYER_OUTBOUND_HOST_RPS can lower Scryer’s request rate to public outbound hosts, but it does not change routing or proxy configuration.
Verify The Configuration
Section titled “Verify The Configuration”Check the direct listener first, then the browser-facing URL:
curl --fail --silent --show-error http://127.0.0.1:8080/healthcurl --fail --silent --show-error https://scryer.example.com/healthFor a base-path deployment:
curl --fail --silent --show-error https://media.example.com/scryer/healthcurl --fail --silent --show-error https://media.example.com/scryer/health/readycurl --fail --silent --show-error https://media.example.com/scryer/.well-known/oauth-authorization-serverThe OAuth discovery response should use the public HTTPS origin, include the base path when configured, and never advertise an internal container hostname. Finally, open the UI and confirm that live updates work; a page that loads but never updates often indicates a missing WebSocket upgrade.
Troubleshooting
Section titled “Troubleshooting”- Connection refused from another machine: Confirm
SCRYER_BINDis not loopback-only, the host port is published, and the firewall allows the client network. - UI loads but live state does not update: Confirm the proxy supports WebSocket upgrades on
/graphql/wsor<base-path>/graphql/ws. - OAuth discovery advertises HTTP or an internal hostname: Set
SCRYER_PUBLIC_URLto the browser-facing origin and verifyHostandX-Forwarded-Proto. - A subpath returns 404 or loads without assets: Set
SCRYER_BASE_PATHand preserve that prefix on upstream requests. Do not strip it. - Everyone behind the proxy is rate-limited together: Add only the controlled proxy address or narrow CIDR to
SCRYER_RATE_LIMIT_TRUSTED_PROXY_IPS. - Startup reports an invalid bind address: Use a complete socket address such as
127.0.0.1:8080,0.0.0.0:8080, or[::]:8080. - Startup reports a TLS configuration error: Set both TLS paths, confirm they are readable inside the host or container, and verify the files contain PEM data.
Related Pages
Section titled “Related Pages”- Configuration - complete environment-variable reference
- Docker - container layout, ports, and storage mounts
- Login - authentication, OAuth discovery, and passkeys
- Security Settings - in-app authentication and access controls
- Troubleshooting - broader operational diagnostics