Operate the proxy

Run the final failover lab

Demonstrate routing, TLS, balancing, health removal, recovery, logging, and backend privacy in one controlled exercise.

10 minute lesson

~~~

Every lesson so far isolated one behavior. Real proxies run all of them at once, and the interesting failures happen at the seams. The final lab joins every boundary. Start two private backends, one HTTPS proxy, structured logs, health checks, and bounded retries.

Assemble the full configuration

This Caddyfile is the course in one file:

app.lab.test {
  tls internal
  log {
    output file access.json
    format json
  }
  reverse_proxy 127.0.0.1:4001 127.0.0.1:4002 {
    lb_policy round_robin
    health_uri /health
    health_interval 5s
    health_timeout 2s
    lb_try_duration 2s
    lb_retry_match GET
  }
}

Start both backends bound to loopback, validate, run. Confirm the baseline before injecting any fault: both ports appear in responses, the certificate is the local one, access.json grows.

Run the observation loop

Run a repeatable request loop:

for number in {1..20}; do
  curl --silent --show-error --fail https://app.lab.test/ || echo failed
  sleep 0.5
done

Keep it running in one terminal. It’s your client’s-eye view for the whole exercise — every fault you inject either shows up here or it doesn’t, and both results are findings.

Inject faults, one at a time

Work through the sequence: stop one backend, restore it, reload one routing change, and inspect distribution and failures.

Stop backend 4002 mid-loop. You may see a failed line or two before the next health probe, then clean responses from 4001 only. Restore it and watch 4002 rejoin the rotation within a probe interval. Then edit one route, caddy validate, caddy reload, and confirm the loop never misses.

After each fault, write the first failed boundary for every intentional fault. Which layer noticed first — the health check, the retry window, the client loop? If the answer surprises you, that’s the lab working. A fault the loop never saw is a resilience win worth understanding; a fault it saw for ten seconds reveals a probe interval worth tuning.

Finish with the privacy check from the trust module: the backend ports must be unreachable from outside while https://app.lab.test answers.

Clean up deliberately

Keep the whole lab local or on infrastructure you own. And when finished, remove what you installed: the /etc/hosts entries, and the local CA root — caddy untrust removes it from the trust store. Remove local CA trust and stop listeners when finished. A forgotten trusted root on a development machine is a real credential, and cleanup is part of operating a proxy, not an afterthought.

Lesson completed

Take this course offline

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

Get the download library →