Operate the proxy

Reload configuration safely

Validate and reload Caddy without discarding active connections or losing the known good file.

10 minute lesson

~~~

The proxy is the front door for everything behind it. Restarting it to change a route means dropping every connection to every site it serves — which is why proxies support graceful reloads: apply new configuration without stopping the process or refusing traffic.

But zero-downtime machinery doesn’t protect you from loading a broken config. Process discipline does. A safe change has a validated candidate, exact deployment action, smoke test, and rollback target. Miss any of the four and you’re gambling with the front door.

Validate, then reload

caddy validate --config Caddyfile
caddy reload --config Caddyfile

caddy validate parses and provisions the candidate without binding ports — syntax errors and bad directives fail here, at zero cost. Only after it passes does caddy reload hand the file to the running process. Caddy loads the new config, swaps it in, and keeps serving; a config that fails to load is rejected while the old one stays active.

Make the sequence unskippable by chaining it:

caddy validate --config Caddyfile && caddy reload --config Caddyfile

The && means an invalid file never even reaches the reload step.

Watch a live connection cross the reload

The claim behind “graceful” deserves a test. Keep a WebSocket or slow request open during the reload and observe its behavior:

curl --max-time 30 http://127.0.0.1:8080/hang &
caddy reload --config Caddyfile

The in-flight request keeps running on the old configuration while new requests get the new one. That’s the mechanism behind zero-downtime deploys at the proxy layer — old connections drain, new connections land on the new config, and no client sees a refused connection.

Smoke test and keep the way back

A reload that “worked” only proves the config loaded, not that it’s right. Run the route and health smoke tests afterward:

curl --silent --fail http://127.0.0.1:8080/api/users || echo "route broken"

A couple of curls against your critical routes catch the misplaced handle block that validation can’t — validation checks form, not intent.

Finally, the rollback target. Do not overwrite the only known good configuration without version control or a recovery copy. The Caddyfile lives in git, so the recovery procedure is boring: check out the previous version, validate, reload. Boring is the goal. The worst place to reconstruct a working config from memory is mid-outage with the front door broken.

Lesson completed

Take this course offline

Get every free book and course as PDF and EPUB files.

Get the download library →