Configuration Basics
Fluxheim uses TOML. Unknown fields are rejected, so spelling mistakes fail before restart.
Main shape
[server]
listen = ["0.0.0.0:8080"]
default_vhost = "site"
[[vhosts]]
name = "site"
hosts = ["example.com"]
For multi-tenant deployments, enable [server.host_routing].strict = true so missing or invalid host identity returns 400 and unknown hosts return 421 instead of reaching the default site.
How config is organized
| Area | What belongs there |
|---|---|
server | Listeners, global limits, trusted proxy handling, and redirects. |
tls | Global TLS backend and compatibility policy. |
cache | Process-wide cache defaults and storage tiers. |
vhosts | Hostnames, routes, web roots, proxy settings, PHP, TLS, and access policy. |
metrics | Prometheus and export listeners for operational visibility. |
Route shape
[[vhosts.routes]]
name = "app"
path_prefix = "/app/"
methods = ["GET", "HEAD", "POST"]
max_request_body_bytes = "16MiB"
[vhosts.routes.proxy]
upstreams = ["127.0.0.1:3000"]
A route has one matcher and one action. Exact paths win first, then longest prefixes, then regex routes when regex support is enabled, then one fallback route.
HTTP response security
HTTP response-security profiles are optional. Start with baseline; use cross-origin isolation only after testing every script, font, image, sign-in flow, and embedded resource.
[headers.response.hardening]
profile = "baseline"
| Profile | What it does |
|---|---|
off | Keeps the opt-in hardening headers disabled. |
baseline | Adds conservative browser isolation and resource-policy defaults suitable for most sites. |
cross-origin-isolated | Enables strict cross-origin isolation for applications that have tested every external dependency. |
Neither profile enables HSTS or CSP. Configure those separately after testing them against the real site.
Standards-based response metadata
Response metadata is disabled by default. Enable only the fields you need; Fluxheim derives them from the actual cache result, proxy failure, and final response bytes without exposing cache keys, backend addresses, DNS names, or raw errors.
[headers.response.metadata]
identifier = "edge-gateway"
cache_status = true
proxy_status = true
content_digest = true
repr_digest = true
| Response field | Reported information |
|---|---|
Cache-Status | RFC 9211 cache outcomes such as hit, miss, stale forwarding, revalidation, expiry, and bypass. |
Proxy-Status | RFC 9209 low-cardinality details for failures generated by Fluxheim. |
Content-Digest | RFC 9530 SHA-256 over the final HTTP message content after compression. |
Repr-Digest | SHA-256 only when Fluxheim holds the complete selected representation. |
Live snapshots and rollback
Authenticated snapshots can publish a validated candidate, replace the live router, and roll back without restarting normal routing-only deployments. Each request stays on one router generation from start to finish.
- Keep the snapshot store in a dedicated private directory; existing non-private directories and filesystem roots are rejected.
- Use a process upgrade when background load-balancer health or discovery services are active.
- Run snapshot integrity checks after publication or rollback and verify the selected generation survives restart.
Safe habits
- Run
fluxheim --check-configbefore reloads. - Use one vhost per site or application boundary.
- Keep secrets in files, environment, or container secrets, not in public docs.
- Keep config files and every existing parent directory under trusted ownership and not writable by group or other users.
- Replace the process when TLS, listeners, streams, UDP, ACME, cache purging, tracing, or managed PHP-FPM process settings change; ordinary routing and request-time policy can use a snapshot reload.
- Use route-level limits for uploads and expensive application paths.
- Keep admin and metrics listeners private.