Skip to content

Directives

Each entry states the syntax, the default when the directive is absent, and where the directive may appear. Version attestation, the Since: line that would state when a directive was introduced, is not published yet.

📖 This page documents a starting subset. Directives that are accepted but not yet documented here are still validated by pingclair validate; a directive the server does not implement is refused by name rather than accepted silently.

Syntax: encode <format> [<format> ...]
Default: no compression
Context: site block

Compresses responses. Arguments are listed in preference order, so the first format the client accepts is used. Supported formats are zstd and gzip.

Asking for Brotli is a compile error rather than a silent downgrade to gzip: the proxy has no streaming Brotli encoder, so the option cannot be honored.

example.com {
encode zstd gzip
file_server ./public
}
Syntax: file_server [<root>]
Default: disabled
Context: site block

Serves files from disk, with MIME type detection, range requests, and ETag and Last-Modified validation. The optional argument sets the root for this directive alone. When it is omitted, the site root set by root is used.

localhost:8080 {
file_server ./public
}
Syntax: header [<matcher>] <field> <value>
header [<matcher>] {
<field> <value> # set
+<field> <value> # append
-<field> # remove
set <field> <value> # set, spelled explicitly
}
Default: none
Context: site block

Adds, replaces, or removes response headers. A bare field name sets the header; prefixing the field with + appends and with - removes.

example.com {
header {
X-Frame-Options "DENY"
X-Content-Type-Options "nosniff"
Strict-Transport-Security "max-age=31536000; includeSubDomains"
-X-Powered-By
}
}
Syntax: log [<name>] { <options> }
Default: no access sink
Context: site block, global options

Configures an access log sink. A bare log enables the default sink for the site; log <name> { ... } configures a named logger, and log <name> without a block refers to a channel declared in the global options.

Block options include the destination and format (output, format), the hostnames selector, include and exclude filters, sampling, and file rotation settings (mode, dir_mode, roll_*).

example.com {
log {
output file /var/log/pingclair/access.log
}
}

Records are batched before they are written, and a sink that cannot keep up drops records and counts them in pingclair_access_log_dropped_total. Writing every request to a system journal also carries the journal receiver’s cost.

Syntax: reverse_proxy [<matcher>] <upstream> [<upstream> ...]
reverse_proxy [<matcher>] { ... }
Default: none
Context: site block

Forwards requests to one or more upstreams. The default load-balancing policy is round robin. Hostname upstreams are re-resolved on the interval set by dns_refresh, so a backend that restarts on a new address is followed without an operator action; a failed lookup keeps the previous address in rotation.

:80 :8080 {
reverse_proxy {
lb_policy least_conn
to 10.0.0.1:8080 {
weight 3
}
to 10.0.0.2:8080
to 10.0.0.3:8080 {
backup
}
health_check {
path /health
interval 5s
timeout 2s
status 200 204
consecutive_failure 3
consecutive_success 2
}
}
}

Active health checks run out of band, so a failed backend leaves rotation before a user request reaches it, and rejoins after the configured number of successful probes. A backup upstream is used only when every primary upstream is unavailable.

Syntax: root [<matcher>] <path>
Default: none
Context: site block

Sets the site root. file_server can take a root of its own, but setting it here is what lets the file server and other file-handling directives agree on a single location.

example.com {
root * /srv/public
file_server
}
Syntax: tls <mode>
tls { <options> }
Default: automatic HTTPS for public names
Context: site block

Controls how certificates are obtained.

Mode Behavior
tls auto Obtains public certificates over ACME and renews them.
tls internal Issues from a persistent local certificate authority. The root is published at $PINGCLAIR_TLS_STORE/internal/root.crt and must be trusted by clients.
tls { cert ...; key ... } Uses the certificate and key files named in the block.

The block form also enables HTTP/3 with http3, and supports DNS-01 issuance with dns cloudflare <token>, which is the only DNS provider implemented. Naming another provider is refused at startup rather than accepted and ignored, because DNS-01 is what makes wildcard certificates possible.

example.com {
tls {
cert /etc/pingclair/certs/example.com.pem
key /etc/pingclair/certs/example.com.key
http3
}
reverse_proxy localhost:3000
}

Global options are written in the unnamed block at the top of the file.

Option Syntax Notes
admin admin <address> [<token>] Admin API listener. Without a token, only loopback connections are accepted.
auto_https auto_https on | off | disable_redirects Controls automatic HTTPS and the port 80 redirect.
dns_refresh dns_refresh <duration> Re-resolution interval for hostname upstreams. off pins the addresses resolved at startup.
email email <address> ACME account email used for issuance.
trusted_proxies trusted_proxies <cidr> [<cidr> ...] Which peers may assert client identity headers. Changes require a restart.
{
email admin@example.com
admin 127.0.0.1:2019
dns_refresh 30s
}