Skip to Content
DeployReverse proxy

Reverse proxy

DBLoom serves plain HTTP on port 3000, so a proxy in front must terminate TLS and forward requests correctly.

What the proxy must do

DBLoom trusts forwarded headers only from peers in DBLOOM_TRUST_PROXY. Unset, it trusts any private-range peer (10/8, 172.16/12, 192.168/16, fc00::/7, loopback) on a non-loopback bind, and the exposure report warns. Setting a CIDR list of your proxy network is recommended, and is the safe choice if the container port could ever be reached by something other than the proxy. Your proxy must:

  1. Forward the original Host, with the port if it is not the default. Hosts outside DBLOOM_ALLOWED_HOSTS (default: the origin host) get 421.
  2. Set X-Forwarded-For from the real peer, replacing any client value. In nginx use $remote_addr, not $proxy_add_x_forwarded_for.
  3. Set X-Forwarded-Proto to the scheme the client used. If the proxy reports http for an https origin, credential pages and functions get 403.
  4. Publish no app port. Close port 3000 to everything but the proxy.
  5. Cap request bodies. The proxy is the main size limit. The app caps its own routes at 1 MiB for server functions and 64 KiB for others. Uploads have their own limit, DBLOOM_IMPORT_MAX_MIB.
  6. Raise the read timeout for large imports. Traefik: entryPoints.<name>.transport.respondingTimeouts.readTimeout (default 60 s). nginx: proxy_read_timeout and client_max_body_size.
  7. Redirect http to https. Leave HSTS to the app, which sends it on an https origin.

Tested configs (npm run test:e2e:proxy, CI on main): Traefik 3 (full suite), Caddy 2 (headers and forwarding), nginx 1 (headers, forwarding, body cap). Apache is not tested. The reference files contain test-only lines (a catch-all Host rule, a forced-http router, evil.example, tls internal). The configs below leave them out. The reference files cap bodies at 4 MiB; raise the cap if you import larger files.

Configs

Dynamic config (file provider). Replace the domain and the container address. Set readTimeout in the static config, not here.

http: routers: app: rule: Host(`dbloom.example.com`) entryPoints: [websecure] service: app middlewares: [limit] tls: {} middlewares: limit: buffering: maxRequestBodyBytes: 4194304 # raise to fit your largest import services: app: loadBalancer: servers: - url: http://172.30.0.2:3000
Last updated on