Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
d63d4d5
command-line: document stdin input for `adapt`
mohammed90 Oct 24, 2025
4582cdb
command-line: document `bcrypt-cost`
mohammed90 Oct 24, 2025
4546f48
docs: mention placeholders in reverse_proxy context (#506)
steffenbusch Oct 27, 2025
f4d9f9a
verifiers: document `leaf` verifier and loaders
mohammed90 Oct 30, 2025
ab9544f
command-line: document stdin input for `adapt`
mohammed90 Oct 24, 2025
3353b4e
command-line: document `bcrypt-cost`
mohammed90 Oct 24, 2025
2b58d64
docs: mention placeholders in reverse_proxy context (#506)
steffenbusch Oct 27, 2025
34de580
verifiers: document `leaf` verifier and loaders
mohammed90 Oct 30, 2025
f6e03a7
Log sampling config
francislavoie Nov 12, 2025
d033f7d
tls.context namespace
francislavoie Nov 12, 2025
fe412b9
keepalive globals
francislavoie Nov 12, 2025
ae2e8de
file server file_limit
francislavoie Nov 12, 2025
382a3a3
vars CEL and CEL placeholder escape
francislavoie Nov 12, 2025
39b12c7
RequestMatcherWithError namespace, cleanup table style
francislavoie Nov 12, 2025
8912bb5
{?query} placeholder
francislavoie Nov 12, 2025
07d842c
Escaped uri placeholders
francislavoie Nov 12, 2025
dff584a
header search placeholders
francislavoie Nov 12, 2025
693b4df
Merge branch 'sync-docs' of https://github.com/caddyserver/website in…
mohammed90 Nov 14, 2025
c8b9782
Add span attributes to tracing documentation (#496)
felix-hilden Jan 13, 2026
90188e6
feat: argon2id auth doc (#486)
GreyXor Jan 13, 2026
7fc7f27
metrics: add `observe_catchall_hosts` docs (#518)
mohammed90 Jan 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/docs/markdown/caddyfile/concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -343,11 +343,21 @@ You can use any placeholders in the Caddyfile, but for convenience you can also
| `{hostport}` | `{http.request.hostport}` |
| `{labels.*}` | `{http.request.host.labels.*}` |
| `{method}` | `{http.request.method}` |
| `{orig_method}` | `{http.request.orig_method}` |
| `{orig_uri}` | `{http.request.orig_uri}` |
| `{orig_path}` | `{http.request.orig_uri.path}` |
| `{orig_dir}` | `{http.request.orig_uri.path.dir}` |
| `{orig_file}` | `{http.request.orig_uri.path.file}` |
| `{orig_query}` | `{http.request.orig_uri.query}` |
| `{orig_?query}` | `{http.request.orig_uri.prefixed_query}` |
| `{path.*}` | `{http.request.uri.path.*}` |
| `{path}` | `{http.request.uri.path}` |
| `{%path}` | `{http.request.uri.path_escaped}` |
| `{port}` | `{http.request.port}` |
| `{query.*}` | `{http.request.uri.query.*}` |
| `{query}` | `{http.request.uri.query}` |
| `{%query}` | `{http.request.uri.query_escaped}` |
| `{?query}` | `{http.request.uri.prefixed_query}` |
| `{re.*}` | `{http.regexp.*}` |
| `{remote_host}` | `{http.request.remote.host}` |
| `{remote_port}` | `{http.request.remote.port}` |
Expand All @@ -365,6 +375,7 @@ You can use any placeholders in the Caddyfile, but for convenience you can also
| `{tls_version}` | `{http.request.tls.version}` |
| `{upstream_hostport}` | `{http.reverse_proxy.upstream.hostport}` |
| `{uri}` | `{http.request.uri}` |
| `{%uri}` | `{http.request.uri_escaped}` |
| `{vars.*}` | `{http.vars.*}` |

Not all config fields support placeholders, but most do where you would expect it. Support for placeholders needs to have been explicitly added to those fields. Plugin authors can [read this article](/docs/extending-caddy/placeholders) to learn how to add support for placeholders in their own modules.
Expand Down
16 changes: 15 additions & 1 deletion src/docs/markdown/caddyfile/directives/basic_auth.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ basic_auth [<matcher>] [<hash_algorithm> [<realm>]] {
}
```

- **&lt;hash_algorithm&gt;** is the name of the password hashing algorithm (or KDF) used for the hashes in this configuration. Default: `bcrypt`
- **&lt;hash_algorithm&gt;** specifies the password hashing algorithm (or key derivation function) used for the hashes in this configuration. Available options include `argon2id`, the default is `bcrypt`.

- **&lt;realm&gt;** is a custom realm name.

Expand Down Expand Up @@ -64,3 +64,17 @@ example.com {
}
```

`argon2id` example

```caddy
example.com {
root * /srv

basic_auth /secret/* argon2id {
# Username "Bob", password "hiccup"
Bob $argon2id$v=19$m=47104,t=1,p=1$zJPvVe48N64JUa9MFlVhiw$b5Tznu0PxnA4TciY6qYe2BFPxncF1ePQaeNukHhH1cU
}

file_server
}
```
3 changes: 3 additions & 0 deletions src/docs/markdown/caddyfile/directives/file_server.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ file_server [<matcher>] [browse] {
browse [<template_file>] {
reveal_symlinks
sort <sort_field> [<direction>]
file_limit <number>
}
precompressed [<formats...>]
status <status>
Expand All @@ -64,6 +65,8 @@ file_server [<matcher>] [browse] {

- **sort** <span id="sort"/> changes the default sort for directory listings. The first parameter is the field/column to sort by: `name`, `namedirfirst`, `size`, or `time`. The second argument is an optional direction: `asc` or `desc`. For example, `sort name desc` will sort by name in descending order.

- **file_limit** <span id="file_limit"/> sets a maximum number of files to show in directory listings. Default: `10000`. If the number of files exceeds this limit, only the first N files will be shown, where N is the specified limit.

- **precompressed** <span id="precompressed"/> is the list of encoding formats to search for precompressed sidecar files. Arguments are an ordered list of encoding formats to search for precompressed [sidecar files](https://en.wikipedia.org/wiki/Sidecar_file). Supported formats are `gzip` (`.gz`), `zstd` (`.zst`) and `br` (`.br`). If formats are omitted, they default to `br zstd gzip` (in that order).

All file lookups will look for the existence of the uncompressed file first. Once found Caddy will look for sidecar files with the file extension of each enabled format. If a precompressed sidecar file is found, Caddy will respond with the precompressed file, with the `Content-Encoding` response header set appropriately. Otherwise, Caddy will respond with the uncompressed file as normal. If the [`encode` directive](encode) is enabled, then it may compress the response on-the-fly if not precompressed.
Expand Down
2 changes: 1 addition & 1 deletion src/docs/markdown/caddyfile/directives/header.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ header [<matcher>] [[+|-|?|>]<field> [<value>|<find>] [<replace>]] {

- **&lt;value&gt;** is the header field value, when adding or setting a field.

- **&lt;find&gt;** is the substring or regular expression to search for.
- **&lt;find&gt;** is the regular expression to search for. Placeholders may be used for a dynamic input into the search pattern. The regular expression language used is RE2, included in Go. See the [RE2 syntax reference](https://github.com/google/re2/wiki/Syntax) and the [Go regexp syntax overview](https://pkg.go.dev/regexp/syntax).

- **&lt;replace&gt;** is the replacement value; required if performing a search-and-replace. Use `$1` or `$2` and so on to reference capture groups from the search pattern. If the replacement value is `""`, then the matching text is removed from the value. See the [Go documentation](https://golang.org/pkg/regexp/#Regexp.Expand) for details.

Expand Down
28 changes: 28 additions & 0 deletions src/docs/markdown/caddyfile/directives/log.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ log [<logger_name>] {
output <writer_module> ...
format <encoder_module> ...
level <level>
sampling {
interval <duration>
first <number>
thereafter <number>
}
}
```

Expand Down Expand Up @@ -98,6 +103,15 @@ log [<logger_name>] {

Note that access logs currently only emit `INFO` and `ERROR` level logs.

- **sampling** <span id="sampling"/> configures log sampling to reduce log volume. If sampling is specified, then it is enabled, with the defaults below taking effect. Omitting this disables sampling.

- **interval** is the [duration window](/docs/conventions#durations) over which to conduct sampling. Default: `1s` (disabled).

- **first** is how many logs to keep within a given level and message for a each interval. Default: `100`.

- **thereafter** is how many logs to skip in each interval after the first kept logs. Default: `100`.

For example, with `interval 1s`, `first 5`, and `thereafter 10`, in each 10-second interval the first 5 log entries will be kept, then it will allow through every 10th log entry with the same level and message within that second.


### Output modules
Expand Down Expand Up @@ -605,3 +619,17 @@ foo.example.com {
log foo
}
```

<span id="sampling-example" /> To reduce log volume with sampling, for example to keep the first 5 requests per second, then 1 out of every 10 requests thereafter:

```caddy
example.com {
log {
sampling {
interval 1s
first 5
thereafter 10
}
}
}
```
36 changes: 36 additions & 0 deletions src/docs/markdown/caddyfile/directives/tls.md
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,42 @@ The `http` module obtains the trusted certificates from HTTP endpoints. The `end
- `once` allows a remote server to request renegotiation once per connection.
- `freely` allows a remote server to repeatedly request renegotiation.

### Verifiers

Client certificate verifier modules are executed after validating they are issued from a trusted certificate authority, if the `trust_pool` is configured. The one verifier, currently, shipped in standard Caddy is `leaf`.

#### Leaf

The `leaf` verifier checks if the client certificate is one of a defined set of permitted certificates. The certificate set is loaded using [loader](https://caddyserver.com/docs/modules/tls.client_auth.verifier.leaf#leaf_certs_loaders) modules.

##### Loaders

Standard Caddy distribution bundles 4 loaders, 3 of them are available in Caddyfile.

###### File

The `file` loader loads the set of certificates from specified PEM files.

```caddy-d
... file <pem_files...>
```

###### Folder

The `folder` loader recursively traverses the named directories searching for PEM files to be loaded as accepted client certificates.

```caddy-d
... folder <folders...>
```

###### PEM

The `pem` loader accepts certificates inlined in the Caddyfile in PEM format.

```caddy-d
... pem <pem_strings...>
```

### Issuers

These issuers come standard with the `tls` directive:
Expand Down
12 changes: 10 additions & 2 deletions src/docs/markdown/caddyfile/directives/tracing.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,18 @@ The trace ID and span ID are added to [access logs](/docs/caddyfile/directives/l

```caddy-d
tracing {
[span <span_name>]
span <span_name>
span_attributes {
<attr1> <value1>
<attr2> <value2>
}
}
```

- **&lt;span_name&gt;** is a span name. Please see span [naming guidelines](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.7.0/specification/trace/api.md).
- **&lt;span_attributes&gt;** are additional attributes attached to each recorded span. Many span attributes are set by default according to OTEL [Semantic conventions for HTTP spans](https://opentelemetry.io/docs/specs/semconv/http/http-spans/) like details about the request, response and client.

[Placeholders](/docs/caddyfile/concepts#placeholders) may be used in span names; keep in mind that tracing happens as early as possible, so only request placeholders may be used, and not response placeholders.
[Placeholders](/docs/caddyfile/concepts#placeholders) may be used in span names and attributes. Keep in mind that the span name is set before the request is forwarded, so only request placeholders may be used. All placeholders are available in span attributes.



Expand Down Expand Up @@ -64,6 +69,9 @@ example.com {
handle {
tracing {
span app
span_attributes {
user_id {http.request.cookie.user-id}
}
}
reverse_proxy localhost:8080
}
Expand Down
22 changes: 20 additions & 2 deletions src/docs/markdown/caddyfile/matchers.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,10 +244,10 @@ expression <cel...>

By any [CEL (Common Expression Language)](https://github.com/google/cel-spec) expression that returns `true` or `false`.

Caddy [placeholders](/docs/conventions#placeholders) (or [Caddyfile shorthands](/docs/caddyfile/concepts#placeholders)) may be used in these CEL expressions, as they are preprocessed and converted to regular CEL function calls before being interpreted by the CEL environment.

Most other request matchers can also be used in expressions as functions, which allows for more flexibility for boolean logic than outside expressions. See the documentation for each matcher for the supported syntax within CEL expressions.

Caddy [placeholders](/docs/conventions#placeholders) (or [Caddyfile shorthands](/docs/caddyfile/concepts#placeholders)) may be used in these CEL expressions, as they are preprocessed and converted to regular CEL function calls before being interpreted by the CEL environment. If a placeholder should be passed as a string argument to a matcher function, then the leading `{` should be escaped with a backslash `\` so that it is not preprocessed, for example `file('\{path}.md')`.

For convenience, the matcher name may be omitted if defining a named matcher that consists solely of a CEL expression. The CEL expression must be [quoted](/docs/caddyfile/concepts#tokens-and-quotes) (backticks or heredocs recommended). This reads quite nicely:

```caddy-d
Expand Down Expand Up @@ -861,6 +861,9 @@ In a [CEL expression](#expression), it would look like this:

```caddy-d
vars <variable> <values...>

expression vars({'<variable>': '<value>'})
expression vars({'<variable>': ['<values...>']})
```

By the value of a variable in the request context, or the value of a placeholder. Multiple values may be specified to match any of those possible values (OR'ed).
Expand Down Expand Up @@ -898,12 +901,21 @@ example.com {
}
```

In a [CEL expression](#expression), it would look like this:

```caddy-d
@magic `vars({'magic_number': ['3', '5']})`
```


---
### vars_regexp

```caddy-d
vars_regexp [<name>] <variable> <regexp>

expression vars_regexp('<name>', '<variable>', '<regexp>')
expression vars_regexp('<variable>', '<regexp>')
```

Like [`vars`](#vars), but supports regular expressions.
Expand Down Expand Up @@ -936,3 +948,9 @@ This can be simplified by omitting the name, which will be inferred from the nam
```caddy-d
@magic vars_regexp {magic_number} ^(4.*)
```

In a [CEL expression](#expression), it would look like this:

```caddy-d
@magic `vars_regexp('magic_number', '^(4.*)')`
```
41 changes: 41 additions & 0 deletions src/docs/markdown/caddyfile/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ Possible options are (click on each option to jump to its documentation):
shutdown_delay <duration>
metrics {
per_host
observe_catchall_hosts
}

# TLS Options
Expand Down Expand Up @@ -126,8 +127,12 @@ Possible options are (click on each option to jump to its documentation):
idle <duration>
}
keepalive_interval <duration>
keepalive_idle <duration>
keepalive_count <number>

trusted_proxies <module> ...
client_ip_headers <headers...>

trace
max_header_size <size>
enable_full_duplex
Expand Down Expand Up @@ -938,6 +943,31 @@ The interval at which TCP keepalive packets are sent to keep the connection aliv
```


##### `keepalive_idle`

The duration a connection must be idle before TCP keepalive packets are sent when no other data is being transmitted. Defaults to `15s`.

```caddy
{
servers {
keepalive_idle 1m
}
}
```


##### `keepalive_count`

The maximum number of TCP keepalive packets to send before considering the connection dead. Defaults to `9`.

```caddy
{
servers {
keepalive_count 5
}
}
```


##### `trusted_proxies`

Expand Down Expand Up @@ -1028,6 +1058,17 @@ You can add the `per_host` option to label metrics with the host name of the met
}
```

Due to the infinite cardinality potential in observing all possible hosts may be sent by clients, Caddy will only record metrics for configured hosts, while all other hosts (e.g., attacker.com) are aggregated under "_other" label. To force observation of all hosts, and where potential infinite cardinality is an acceptable risk, you add `observe_catchall_hosts`. Note that adding `observe_catchall_hosts` will not enable `per_host`. However, this is automatically enabled for HTTPS servers (since certificates provide some protection against unbounded cardinality), but disabled for HTTP servers by default to prevent cardinality attacks from arbitrary Host headers.

```caddy
{
metrics {
per_host
observe_catchall_hosts
}
}
```

##### `trace`

Log each individual handler that is invoked. Requires that the log emit at `DEBUG` level ( You may do so with the [`debug` global option](#debug)).
Expand Down
Loading