Proxy foundations
Run a one-command reverse proxy
Put Caddy in front of one backend and confirm the client no longer connects directly to the application port.
10 minute lesson
A reverse proxy accepts the client request and creates a separate upstream request. There are two distinct connections: client to proxy, and proxy to backend. The client sees the proxy address, not the backend listener, and everything the proxy does — routing, TLS, logging, balancing — happens between those two connections.
Caddy can run this whole arrangement from a single command, which makes it perfect for a first experiment.
Start the proxy
With the backend from the previous lesson running on port 4001:
caddy reverse-proxy --from http://127.0.0.1:8080 --to 127.0.0.1:4001 --access-log
--from is the address Caddy listens on. --to is the upstream. --access-log prints every proxied request to the terminal, which is exactly the visibility we want right now.
Verify the two connections
Request port 8080, the proxy’s port:
curl http://127.0.0.1:8080/hello
# {"port":4001,"path":"/hello"}
The response body says port 4001, so the backend handled it. But you connected to 8080. Match this request with the line Caddy printed in its access log: same path, same status. That log line is the proof the proxy was in the middle.
Break the upstream
Now stop the backend process and repeat the request:
curl -i http://127.0.0.1:8080/hello
# HTTP/1.1 502 Bad Gateway
The proxy is still up — it answered you. It just couldn’t complete its own connection to the upstream, and it reported that as a 502 Bad Gateway. This distinction matters for the rest of the course: a proxy error and a backend error look different, and the status code tells you which connection failed.
Restart the backend and confirm the 200 comes back without touching Caddy at all.
Keep the first listener on loopback. Public proxying needs firewall, TLS, application authentication, and origin protection — all of which come later in this course. Exposing port 8080 to a network now would mean anyone on it can reach your backend through the proxy.
Lesson completed