Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/cryguy/hashboard/llms.txt

Use this file to discover all available pages before exploring further.

Hashboard is designed to run behind a TLS-terminating reverse proxy. The proxy handles HTTPS certificates and routes the public hostname to Hashboard’s local port; Hashboard handles everything else. Two environment variables are mandatory in this setup: ORIGIN tells adapter-node what the public URL is, and ADDRESS_HEADER + XFF_DEPTH restore real client IP addresses that the proxy would otherwise hide.

Required environment variables

ORIGIN

ORIGIN=https://hashboard.example.com
SvelteKit’s adapter-node cannot infer the public origin from the incoming request when it sits behind a proxy. ORIGIN is the value it uses to build absolute URLs — most critically the OIDC redirect_uri. If ORIGIN is unset or wrong, OIDC logins will fail with a redirect mismatch error at the identity provider. Set ORIGIN in compose.yaml (Docker) or .env (pm2) before starting Hashboard.

ADDRESS_HEADER and XFF_DEPTH

Set ADDRESS_HEADER and XFF_DEPTH in every production deployment behind a proxy. Without them, adapter-node sees every request as originating from the proxy’s IP address. The login and registration rate limiters key on client IP, so all visitors share one bucket: roughly 10 registration attempts per 15 minutes for the entire instance combined. A single abusive client can lock out all legitimate users. This is not a cosmetic issue — it is a security misconfiguration.
ADDRESS_HEADER=X-Forwarded-For
XFF_DEPTH=1
XFF_DEPTH=1 tells adapter-node to trust exactly one proxy hop. If you have two proxies in front of Hashboard (for example, a CDN in front of nginx), set XFF_DEPTH=2. Do not set it higher than the actual number of trusted proxies you control — an attacker can spoof entries further back in the X-Forwarded-For chain.

Setting these in compose.yaml (Docker)

Uncomment the relevant lines in compose.yaml:
environment:
  ORIGIN: https://hashboard.example.com
  ADDRESS_HEADER: X-Forwarded-For
  XFF_DEPTH: '1'

Setting these in .env (pm2)

Uncomment the relevant lines in .env:
ORIGIN=https://hashboard.example.com
ADDRESS_HEADER=X-Forwarded-For
XFF_DEPTH=1

TLS requirement

TLS is mandatory in production. The session cookie is set with the Secure flag. Over plain HTTP on any non-localhost address, the browser accepts the cookie when you log in but never sends it back on subsequent requests. Sign-in appears to succeed and then immediately “does nothing” — there is no error in the UI or the server log. If sign-in loops silently on a LAN IP or a plain http:// URL, this is the cause. The fix is to put TLS in front of Hashboard, or to test on localhost where Secure cookies are exempt.
The simplest way to obtain a certificate is to let your reverse proxy manage it — Caddy does this automatically with its built-in ACME client, and NPMplus provides a GUI for Let’s Encrypt. For nginx, use Certbot or provision a certificate manually.

nginx example

The following minimal nginx configuration proxies HTTPS traffic to Hashboard running on localhost:3000. Replace hashboard.example.com with your actual hostname and adjust the certificate paths.
server {
    listen 443 ssl;
    server_name hashboard.example.com;

    ssl_certificate     /etc/ssl/certs/hashboard.crt;
    ssl_certificate_key /etc/ssl/private/hashboard.key;

    # Forward the real client IP
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header Host $host;

    # Required for SSE (server-sent events) — disable buffering
    proxy_buffering off;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

server {
    listen 80;
    server_name hashboard.example.com;
    return 301 https://$host$request_uri;
}
proxy_buffering off is important. Hashboard uses server-sent events for live updates; a buffering proxy will hold the stream until it closes rather than forwarding events as they arrive.

Caddy example

Caddy automatically provisions and renews TLS certificates via ACME. A minimal Caddyfile:
hashboard.example.com {
    reverse_proxy localhost:3000
}
Caddy sets X-Forwarded-For by default. Set XFF_DEPTH=1 and ADDRESS_HEADER=X-Forwarded-For in your Hashboard configuration as described above.

NPMplus

NPMplus (Nginx Proxy Manager Plus) provides a GUI for configuring reverse proxy hosts and Let’s Encrypt certificates. After creating a proxy host pointing to http://127.0.0.1:3000 (or the Docker container name if both run in the same Compose network), add custom Nginx configuration in the “Advanced” tab:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_buffering off;
Then set ADDRESS_HEADER=X-Forwarded-For and XFF_DEPTH=1 in Hashboard’s environment.

Build docs developers (and LLMs) love