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:
- Forward the original
Host, with the port if it is not the default. Hosts outsideDBLOOM_ALLOWED_HOSTS(default: the origin host) get 421. - Set
X-Forwarded-Forfrom the real peer, replacing any client value. In nginx use$remote_addr, not$proxy_add_x_forwarded_for. - Set
X-Forwarded-Prototo the scheme the client used. If the proxy reportshttpfor anhttpsorigin, credential pages and functions get 403. - Publish no app port. Close port 3000 to everything but the proxy.
- 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. - Raise the read timeout for large imports. Traefik:
entryPoints.<name>.transport.respondingTimeouts.readTimeout(default 60 s). nginx:proxy_read_timeoutandclient_max_body_size. - Redirect http to https. Leave HSTS to the app, which sends it on an
httpsorigin.
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
Traefik
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