docs(caddy): where the live Caddyfile is, and what the syntax page's claims cost
The page explained matcher ordering beautifully and never said where the file lives — so the next agent hunts for a Caddyfile on the host and finds nothing. Measured on Dankclaw 2026-10-21: Caddy is a rootless Quadlet container (`caddy.container`, a *user* unit, so a root `systemctl is-active caddy` answers `inactive` and means nothing), its config is `/etc/caddy/Caddyfile` **inside the container**, `/etc/caddy` does not exist on the host, and `pgrep -a caddy` prints a config path that no host path satisfies. Version is v2.11.7, which closes the one version-dependent rule on the page: the leading-`/` `rewrite` form needs 2.8.0+, so the `*` disambiguator is legacy in this fleet's config. Also: the seven caddyserver.com links sat in a mid-page "Sources:" paragraph. OKF wants external claims under `# Citations`, so they move there and each entry says which claim it supports. The validate section now points at the container instead of telling you to run the validator on a file that is not there. Refs #64
This commit is contained in:
+47
-15
@@ -1,13 +1,13 @@
|
||||
---
|
||||
type: reference
|
||||
title: Caddyfile Syntax
|
||||
description: Caddy Caddyfile reference — directive and matcher syntax, named matchers, directive sorting, and the handle/route order rule. Grounded in caddyserver.com (fetched 2026-08-28).
|
||||
description: Caddy Caddyfile reference — the syntax that bites (matchers, directive sorting, handle vs route), plus where the fleet's live Caddyfile actually is and how to validate it.
|
||||
resource: https://caddyserver.com/docs/caddyfile
|
||||
tags:
|
||||
- caddy
|
||||
- caddyfile
|
||||
- reverse-proxy
|
||||
verified: 2026-08-28
|
||||
verified: 2026-10-21
|
||||
---
|
||||
|
||||
# Caddyfile Syntax
|
||||
@@ -17,13 +17,28 @@ port). Directives inside the block control how Caddy serves requests. Matchers
|
||||
classify requests. This page records the syntax that trips people up, grounded
|
||||
in the official docs.
|
||||
|
||||
Sources: [caddyfile-tutorial](https://caddyserver.com/docs/caddyfile-tutorial),
|
||||
[matchers](https://caddyserver.com/docs/caddyfile/matchers),
|
||||
[rewrite](https://caddyserver.com/docs/caddyfile/directives/rewrite),
|
||||
[handle](https://caddyserver.com/docs/caddyfile/directives/handle),
|
||||
[forward_auth](https://caddyserver.com/docs/caddyfile/directives/forward_auth),
|
||||
[reverse_proxy](https://caddyserver.com/docs/caddyfile/directives/reverse_proxy),
|
||||
[concepts](https://caddyserver.com/docs/caddyfile/concepts).
|
||||
The syntax below is the parts that bite; the sources are listed under
|
||||
`# Citations` at the end.
|
||||
|
||||
## Where the live Caddyfile is
|
||||
|
||||
Caddy runs as a **rootless Quadlet container** on Dankclaw
|
||||
(`~/.config/containers/systemd/caddy.container`, unit `caddy.service`). It is a *user* unit:
|
||||
`systemctl is-active caddy` as root answers `inactive` and means nothing — ask the user
|
||||
manager (`systemctl --user`). Its config path lives inside the container, so there is **no
|
||||
`/etc/caddy` on the host**: a host-side search for a Caddyfile comes up empty, and
|
||||
`pgrep -a caddy` prints `--config /etc/caddy/Caddyfile` for a path that does not exist
|
||||
locally. Everything about it goes through `podman exec`:
|
||||
|
||||
```bash
|
||||
ssh dankclaw podman exec caddy cat /etc/caddy/Caddyfile
|
||||
ssh dankclaw podman exec caddy caddy version # v2.11.7, read 2026-10-21
|
||||
ssh dankclaw systemctl --user restart caddy
|
||||
```
|
||||
|
||||
The live file's own header says what it fronts (both hosts, `franksdank.cloud` names,
|
||||
Pi-hole-resolved); its deployment history belongs to the serverAppConfigs vault
|
||||
(`Infrastructure/Caddy.md`), not to this syntax page.
|
||||
|
||||
## Directive and matcher syntax
|
||||
|
||||
@@ -116,9 +131,10 @@ Use `handle` for mutually exclusive branches (for example, per-path pages). Use
|
||||
rewrite [<matcher>] <to>
|
||||
```
|
||||
|
||||
`<to>` is the new URI (path or query). If `<to>` starts with `/`, Caddy 2.8.0+
|
||||
parses it directly. Before 2.8.0, a leading `/` was confused with a path
|
||||
matcher, so a `*` disambiguator was needed: `rewrite * /index.html`.
|
||||
`<to>` is the new URI (path or query). If `<to>` starts with `/`, Caddy 2.8.0+ parses it
|
||||
directly. Before 2.8.0 a leading `/` was confused with a path matcher, so a `*`
|
||||
disambiguator was needed: `rewrite * /index.html`. The fleet runs v2.11.7, so write the
|
||||
plain form.
|
||||
|
||||
`try_files <files...>` rewrites to the first listed file that exists. It is the
|
||||
clean way to serve a named file for a path prefix:
|
||||
@@ -244,6 +260,22 @@ wins). Put the specific `handle /admin*` before the catch-all `handle`.
|
||||
|
||||
## Validate before you deploy
|
||||
|
||||
Run `caddy validate --config <file> --adapter caddyfile` before loading a
|
||||
Caddyfile. A placeholder hash (not a real bcrypt hash) fails validation with
|
||||
`base64-decoding password`. Render the real hashes first, then validate.
|
||||
Run `caddy validate --config <file> --adapter caddyfile` before loading a Caddyfile. A
|
||||
placeholder hash (not a real bcrypt hash) fails validation with `base64-decoding password`.
|
||||
Render the real hashes first, then validate. On the fleet's Caddy the file is inside the
|
||||
container — run the validator there, see
|
||||
[Where the live Caddyfile is](#where-the-live-caddyfile-is).
|
||||
|
||||
# Citations
|
||||
|
||||
- [Caddyfile tutorial](https://caddyserver.com/docs/caddyfile-tutorial) and
|
||||
[concepts](https://caddyserver.com/docs/caddyfile/concepts) — directive form, the three
|
||||
matcher token forms, and the canonical sort order behind the `handle`/`route` rule.
|
||||
- [matchers](https://caddyserver.com/docs/caddyfile/matchers) — exact vs `*` prefix path
|
||||
matching, named matchers, `matcher is defined more than once`.
|
||||
- [rewrite](https://caddyserver.com/docs/caddyfile/directives/rewrite),
|
||||
[handle](https://caddyserver.com/docs/caddyfile/directives/handle) and
|
||||
[reverse_proxy](https://caddyserver.com/docs/caddyfile/directives/reverse_proxy) — the
|
||||
2.8.0 leading-`/` change, `handle` vs `route` semantics, `trusted_proxies`.
|
||||
- [forward_auth](https://caddyserver.com/docs/caddyfile/directives/forward_auth) — the
|
||||
outpost-before-gate ordering and `copy_headers`.
|
||||
|
||||
Reference in New Issue
Block a user