Skip to content

Dwaarfile Reference

The Dwaarfile is Dwaar’s configuration format. It is designed to be readable, minimal, and production-ready with zero boilerplate.

Dwaar looks for configuration in this order:

  1. --config CLI flag: dwaar --config /path/to/Dwaarfile
  2. ./Dwaarfile in the current directory
  3. /etc/dwaar/Dwaarfile

A Dwaarfile consists of domain blocks. Each block configures one domain:

domain.com {
directive value
directive value
}

Rules:

  • One domain per block
  • Directives are one per line
  • Comments start with #
  • No semicolons, no quotes around simple values
  • Indentation is convention (2 or 4 spaces), not required

The table below lists every directive Dwaar recognises. Follow the link in the Reference column for full syntax, options, and examples.

DirectiveDescriptionReference
reverse_proxyForward requests to one or more upstream backendsReverse Proxy
file_serverServe static files from diskFile Server
php_fastcgiForward requests to a PHP-FPM socket or addressFastCGI
redirIssue an HTTP redirect to a new URLRedirects & Rewrites
rewriteRewrite the request URI internally before routingRedirects & Rewrites
uriStrip a path prefix, append a suffix, or replace path segmentsRedirects & Rewrites
handleGroup directives that apply to a specific path prefixHandle & Route
handle_pathLike handle, but strips the matched prefix from the request pathHandle & Route
routeEvaluate a group of directives in strict orderHandle & Route
respondWrite a static response body and status codeRespond & Errors
errorSynthesise an error with a given status codeRespond & Errors
abortClose the connection immediately with no responseRespond & Errors
handle_errorsDefine how Dwaar handles error responsesRespond & Errors
tlsControl TLS mode: auto, off, or manual with explicit cert pathsAutomatic HTTPS
encodeCompress responses using Brotli or GzipCompression
cacheCache upstream responses at the edgeCaching
rate_limitEnforce per-IP request rate limits; returns 429 on breachRate Limiting
ip_filterAllow or deny requests by IP address or CIDR rangeIP Filtering
basic_authProtect routes with HTTP Basic authenticationBasic Auth
forward_authDelegate authentication to an external serviceForward Auth
headerSet or delete response headersinline
request_headerSet or delete request headers before proxyinginline
logConfigure per-domain access loggingLogging
rootSet the filesystem root used by file_server and try_filesFile Server
try_filesAttempt a list of paths in order before falling throughFile Server
bindBind the server socket to a specific address or interfaceinline
request_bodySet a maximum allowed request body sizeinline
wasm_pluginLoad a WebAssembly plugin for custom request/response logicWASM Plugins
varsDefine named variables available as placeholdersPlaceholders
mapMap an input value to an output variable via a lookup tablePlaceholders
@nameDeclare a named matcher for reuse across directivesNamed Matchers
metricsExpose a Prometheus /metrics endpointPrometheus
skip_logSuppress access log entries for matched requestsLogging

Directives marked inline are simple enough to be fully described inline in examples below rather than warranting a dedicated page.

header — Set or delete response headers:

example.com {
reverse_proxy localhost:8080
header X-Frame-Options "DENY"
header -Server # delete the Server header
}

request_header — Set or delete request headers before the request is forwarded:

example.com {
reverse_proxy localhost:8080
request_header X-Real-IP {remote_host}
request_header -Cookie # strip cookies before proxying
}

bind — Bind to a specific address instead of all interfaces:

internal.example.com {
bind 10.0.0.1
reverse_proxy localhost:9000
}

request_body — Reject requests whose body exceeds a size limit:

upload.example.com {
reverse_proxy localhost:8080
request_body 10MB
}

The following are active for every domain with no configuration required:

FeatureDefaultOverride
TLSauto (Let’s Encrypt)tls off or tls manual
HTTP → HTTPS redirectOnDisabled when tls off
CompressionOn (Brotli/Gzip)encode off
Security headersOn (HSTS, X-Content-Type-Options, etc.)Not yet configurable
HTTP/2OnNot yet configurable
Access loggingOn (JSON to stdout)log directive or skip_log
X-Request-IdOn (UUID v7)Not yet configurable
Proxy headersOn (X-Real-IP, X-Forwarded-For)Not yet configurable
# Production API — rate-limited, no analytics, metrics exposed
api.example.com {
reverse_proxy localhost:3000
rate_limit 200/s
encode on
metrics /internal/metrics
log {
output file /var/log/dwaar/api.log
}
skip_log /healthz
}
# Marketing site — static files with a fallback to the SPA index
www.example.com {
root /var/www/marketing
try_files {path} /index.html
file_server
encode on
}
# PHP application via FastCGI
app.example.com {
root /var/www/app/public
php_fastcgi unix//run/php/php8.3-fpm.sock
}
# Admin panel — forward auth, no public TLS
admin.internal {
bind 10.0.0.0/8
tls off
forward_auth http://authd:9001/validate {
copy_headers X-User X-Role
}
reverse_proxy localhost:5000
}
# Redirect bare domain to www
example.com {
redir https://www.example.com{uri} permanent
}

Check your Dwaarfile for errors without starting the server:

Terminal window
dwaar validate
# Config valid.
dwaar validate --config /path/to/Dwaarfile
# Config valid.

Format your Dwaarfile consistently:

Terminal window
dwaar fmt
# Formatted 3 domain blocks.
dwaar fmt --check
# Exit code 1 if unformatted (useful in CI).