Repository navigation
Reverse Proxy and LAN Access
Nooklet publishes to 127.0.0.1:42021 by default. That loopback-only default is appropriate for first setup and for a reverse proxy running on the same host. Deliberately choose one ingress pattern before exposing the app beyond the host.
| Pattern | Recommended use | APP_BIND_ADDRESS |
TLS |
|---|---|---|---|
| Same-host reverse proxy | Preferred for a stable hostname and any remote access | 127.0.0.1 |
Terminate at the proxy |
| Direct trusted-LAN access | Small isolated LAN where direct IP/port access is acceptable | Specific LAN address if practical, otherwise 0.0.0.0
|
Not built in; HTTPS still recommended |
| VPN plus loopback/proxy | Remote access without public app ingress | Usually 127.0.0.1, topology-dependent |
Provided by proxy/VPN design |
| Direct public port forwarding | Not recommended | — | Nooklet is not an internet-edge TLS server |
The relevant .env values are:
APP_URL=https://nooklet.example.com
APP_BIND_ADDRESS=127.0.0.1
APP_PORT=42021
TRUST_PROXY_HEADERS=true-
APP_URLis the browser-facing origin, includinghttps://and any non-default external port. -
APP_BIND_ADDRESSandAPP_PORTcontrol Docker's host-side port publishing. - The container always listens on port
42021. -
TRUST_PROXY_HEADERSaffects client-address attribution for abuse controls; it does not make a proxy trusted for authorization.
Use a dedicated origin such as https://nooklet.example.com, not an unconfigured path prefix such as https://example.com/nooklet.
After changing any value, recreate the container:
docker compose up -d --build --force-recreateKeep Nooklet bound to loopback and make the proxy the only network-facing listener. The proxy should:
- terminate TLS with a valid certificate;
- accept only the intended hostname;
- forward the original
Hostand scheme; - overwrite client-address headers rather than trusting client-supplied values; and
- forward to
127.0.0.1:42021.
nooklet.example.com {
reverse_proxy 127.0.0.1:42021 {
header_up Host {host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-For {remote_host}
header_up X-Real-IP {remote_host}
}
}server {
listen 443 ssl;
server_name nooklet.example.com;
# Configure ssl_certificate and ssl_certificate_key for this host.
location / {
proxy_pass http://127.0.0.1:42021;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
}
}These are minimal upstream examples, not complete proxy hardening. Apply your proxy's maintained TLS, logging, request-size, timeout, and access-control policy.
127.0.0.1 inside the proxy container refers to the proxy container itself. Choose one controlled topology:
- place proxy and Nooklet on an explicitly managed Docker network and proxy to the Nooklet service name; or
- publish Nooklet on a host address reachable only by the proxy and firewall it from other clients.
Do not use network_mode: host or publish broadly merely to avoid defining the network. If adding Nooklet to another Docker network, keep the data and media mounts unchanged and ensure the upstream name is exact and stable.
Leave TRUST_PROXY_HEADERS=false for direct connections. Set it to true only if all of the following are true:
- every request reaches Nooklet through the trusted proxy;
- direct access to the published app port is blocked or loopback-only; and
- the proxy overwrites
X-Forwarded-Forand/orX-Real-IPwith a validated client address.
Nooklet uses only a syntactically valid IP from the trusted headers. If a client can connect directly or inject the first forwarded address, source-based login/bootstrap controls can be misattributed.
For a multi-proxy chain, normalize the client address at the last trusted hop. Do not copy arbitrary incoming X-Forwarded-For unchanged.
For intentional direct access from the local network:
APP_URL=http://192.168.1.50:42021
APP_BIND_ADDRESS=0.0.0.0
APP_PORT=42021
TRUST_PROXY_HEADERS=falseThen recreate and verify:
docker compose up -d --build --force-recreate
docker compose ps
docker compose port app 42021From a second device, open http://192.168.1.50:42021/api/health, then the application.
Security requirements for direct LAN publishing:
- reserve a stable address or DNS name for the host;
- limit the host firewall rule to trusted private subnets;
- do not forward the port on the router;
- do not set
TRUST_PROXY_HEADERS=truewithout an actual proxy; - prefer HTTPS even on a LAN when credentials cross shared Wi-Fi or untrusted switches; and
- keep the first-admin bootstrap closed before widening the bind address.
0.0.0.0 publishes on every host interface. A specific host IP is narrower when Docker and the operating system support it.
These settings solve different problems:
| Setting | Direction | Purpose |
|---|---|---|
APP_BIND_ADDRESS / APP_PORT
|
Inbound | Where browsers and proxies can reach Nooklet on the Docker host. |
APP_URL |
Browser-facing identity | Canonical origin used by authentication and generated navigation. |
TRUST_PROXY_HEADERS |
Inbound metadata | Whether a proxy-supplied client IP can be used for abuse controls. |
PRIVATE_SERVICE_HOST_ALLOWLIST |
Outbound | Exact private hosts Nooklet may contact for integrations. |
ALLOW_PRIVATE_SERVICE_HOSTS |
Outbound | Broad private-host permission for a tightly trusted LAN. |
A reverse proxy does not automatically authorize Nooklet to contact Plex, Tautulli, an AI server, or a private indexer.
For an exact outbound allowlist:
PRIVATE_SERVICE_HOST_ALLOWLIST=plex.local;tautulli.local;192.168.1.25
ALLOW_PRIVATE_SERVICE_HOSTS=falseEntries are hostnames/IPs only—no scheme, port, path, CIDR, or wildcard. Recreate Nooklet after changes. Use the same exact hostname in the connection URL.
After proxy or LAN changes:
-
docker compose psshows the expected host publish address. -
http://127.0.0.1:42021/api/healthworks from the Docker host for a same-host proxy deployment. - The external URL redirects unauthenticated users to
/loginon the same expected origin. - Browser developer tools show HTTPS with no mixed-content errors.
- Response headers include
Content-Security-Policy,Strict-Transport-Security, andX-Content-Type-Options. - Login succeeds and sign-out returns to the expected origin.
- A private integration test succeeds only for explicitly authorized hosts.
| Symptom | Likely cause | Resolution |
|---|---|---|
Proxy returns 502 Bad Gateway
|
Wrong upstream address or Nooklet is not healthy. | Query the loopback probe on the Nooklet host and inspect docker compose ps; a containerized proxy cannot use its own loopback for Nooklet. |
Redirect or sign-in uses localhost
|
APP_URL is still the local default or the container was not recreated. |
Set the external origin and force-recreate. |
| Browser cannot connect from LAN | App is still loopback-bound or a host firewall blocks it. | Inspect docker compose port app 42021, adjust the deliberate bind/firewall policy, and recreate. |
| Login attempts appear to share one source | Proxy headers are not trusted or the proxy reports only its own address. | Configure the proxy to overwrite client headers, then enable TRUST_PROXY_HEADERS. |
| Client can spoof source IP | Nooklet is directly reachable while proxy headers are trusted, or the proxy forwards incoming headers unchanged. | Close direct ingress and overwrite headers at the last trusted proxy. |
| Private integration says host is blocked | Inbound publishing was confused with outbound authorization. | Add the exact integration hostname/IP to PRIVATE_SERVICE_HOST_ALLOWLIST and recreate. |
| Connection test rejects a redirect | Outbound redirects are intentionally refused. | Configure the final direct HTTP(S) endpoint rather than a URL that redirects. |
See Troubleshooting for container, storage, and database failures.
Nooklet repository · Features · User guide · Engineering dossier · Issues · Private security advisory
Documentation last reviewed against main: August 19, 2026.
Nooklet
Start here
- Getting started
- Guided Docker setup
- Docker installation
- Native installation (advanced)
- First-time setup
Configure
Use Nooklet
- Discover and recommendations
- Library and requests
- YouTube monitoring
- Downloads and import
- Watch history
- Automation and notifications
Operate
- Health and diagnostics
- Backup, restore, upgrades
- Accounts and users
- Troubleshooting
- Multi-instance boundaries
Engineering