Operate Caddy
Protect configuration and recovery state
Keep the admin API private, understand native JSON updates, preserve Caddy storage, and finish a tested recovery runbook.
10 minute lesson
Two assets decide whether a bad day is a blip or a disaster: control of the running configuration, and the state Caddy needs to come back after a loss. This last lesson covers both.
Caddy is controlled at runtime through its admin API, listening on localhost:2019. Every caddy reload you’ve run in this course used it. You can read the live configuration directly:
curl http://localhost:2019/config/ | jq .
That JSON is the actual running configuration — the truth, even if someone edited the Caddyfile without reloading. The API also accepts POST and PATCH requests that change configuration on the fly, which is exactly why it must stay private. Whoever reaches this endpoint owns the server: they can reroute your traffic anywhere. The default localhost binding is correct. Leave it alone, and if you ever need remote administration, tunnel over SSH instead of exposing the port.
The second asset is Caddy’s storage: the data directory holding certificates, private keys, and the ACME account. Lose it and Caddy re-issues everything from scratch — slow at best, rate-limited at worst. Back it up with the built-in command:
caddy storage export --output caddy-storage.tar
storage export produces a tar archive of the whole storage. Treat it like a private key, because it contains your private keys: encrypt it, store it apart from your configuration backups, and never commit it to a repository.
Restore is the mirror image:
caddy storage import --input caddy-storage.tar
A backup you haven’t restored is a guess. Run the drill once in a throwaway VM or container: install Caddy, restore the Caddyfile, import the storage, start the service, and confirm the site comes up over HTTPS. Then check the runtime log — no new certificate issuance means the restored state actually worked.
Your full recovery kit is three things: the Caddyfile in version control, the storage export somewhere encrypted, and the notes from lesson one about your binary version and modules. With those, a dead server is an hour of calm work instead of a scramble against expiring certificates.
Lesson completed