In this article I am going to show you how to use Caddy as a reverse proxy and also covering some additional features such as multiple upstreams, health checks and load balancing.
Mock Server #
Since you are doing reverse proxy, you need something to reverse proxy to. You can set up a mock server as you want, it has to be nothing special, just a basic server with an endpoint.
I am going to use a simple server written in Go that logs each request's URL, Method and Headers.
Don't worry if you are unable to understand the following piece of code.
package main import ( "fmt" "net/http" "os" ) func main() { if len(os.Args) < 3 { fmt.Println("Example: go run main.go <name> <port>") os.Exit(1) } serverName := os.Args[1] serverPort := os.Args[2] fmt.Printf("starting server %s on port %s\n", serverName, serverPort) http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Printf("----> Received on server %s\n", serverName) fmt.Printf("URL: %s %s\n", r.Method, r.URL.String()) fmt.Println("Headers:") for key, value := range r.Header { fmt.Printf("\t%s: %v\n", key, value) } w.Write([]byte("Hello From Server " + serverName)) fmt.Println("<---- Response sent") }) http.ListenAndServe(fmt.Sprintf(":%s", serverPort), nil) }
main.go
The above takes in a server name and a port, if you have go
installed you can run it using go run main.go server-1 8881
.
Reverse Proxy #
Let's write a basic reverse proxy that listens on port 8000 and forwards all traffic to a server running on port 8881.
Before doing this, start the mock server on port 8881.
go run main.go server-1 8881
Now comes the Caddyfile.
:8000 reverse_proxy localhost:8881
Caddyfile
Send a request on port 8000 and you get back response from the server.
$ curl -X GET localhost:8000
Hello From Server server-1
Meanwhile in the server console, you can see the complete request log.
$ go run main.go server-1 8881
----> Received on server server-1
URL: GET /
Headers:
User-Agent: [curl/7.86.0]
Accept: [*/*]
X-Forwarded-For: [127.0.0.1]
X-Forwarded-Host: [localhost:8000]
X-Forwarded-Proto: [http]
Accept-Encoding: [gzip]
<---- Response sent