Reverse proxy and client IPs
Day Planner listens on plain HTTP on port 8303. Put a reverse proxy in front of it for HTTPS, and tell Day Planner how the proxy passes on the visitor’s IP address, so sign-in rate limits apply per visitor.
HTTPS with Caddy
Section titled “HTTPS with Caddy”This Caddyfile gets a certificate automatically and forwards to the app.
tasks.example.com { reverse_proxy localhost:8303}Set BETTER_AUTH_URL=https://tasks.example.com to match. Caddy adds X-Forwarded-For and X-Forwarded-Host by default.
Tell Day Planner where the IP comes from
Section titled “Tell Day Planner where the IP comes from”Rate limits count requests per visitor IP. Behind a proxy, every request comes from the proxy, so Day Planner reads the visitor’s IP from a header instead. Pick the case that matches your setup:
| Setup | Settings |
|---|---|
| One proxy (Caddy, nginx, Traefik) on the same server | Defaults are fine: CLIENT_IP_HEADER=x-forwarded-for. Add the proxy’s address to TRUSTED_PROXIES if it isn’t 127.0.0.1, for example the Docker network 172.16.0.0/12. |
nginx setting X-Real-IP |
CLIENT_IP_HEADER=x-real-ip |
| Cloudflare in front, and the server only reachable through Cloudflare | CLIENT_IP_HEADER=cf-connecting-ip |
| Cloudflare in front, but the server also reachable directly | Keep x-forwarded-for and list your proxy in TRUSTED_PROXIES. Anyone who bypasses Cloudflare could otherwise set CF-Connecting-IP to anything. |
With x-forwarded-for, Day Planner reads the list of addresses from right to left and skips the ones in TRUSTED_PROXIES. The first address that isn’t a trusted proxy is the visitor. A visitor can’t fake it, because they can only add entries to the left.
Server Actions and the forwarded host
Section titled “Server Actions and the forwarded host”Forms such as setup and Settings use Next.js Server Actions, which check that the Origin header matches the host. Most proxies pass X-Forwarded-Host correctly, so this works without extra configuration. If a form fails with “Invalid Server Actions request” in the logs, make sure your proxy forwards the original Host.
See also
Section titled “See also”- Configuration:
CLIENT_IP_HEADER,TRUSTED_PROXIESandTRUSTED_ORIGINS - Too many attempts: what rate limiting looks like to users
- Running more than one instance: rate limits across containers