Here's how you can configure Caddy to support load balancing:

{
    debug
}

localhost {
    push

    encode zstd gzip

    # Replace backends health checks and provide one for this LB
    respond /health 200
        
    log {
        output stdout
        format console
    }
    
    reverse_proxy * {
        # Specify backend here
        to 127.0.0.1:8001
        to 127.0.0.1:8002
        to 127.0.0.1:8003

        lb_policy round_robin
        lb_try_duration 1s
        lb_try_interval 250ms

        health_path     /health # Backend health check path
        # health_port     80 # Default same as backend port
        health_interval 10s
        health_timeout  2s
        health_status   200
    }
}

The following directives are used:

  • debug: enables debug mode, which sets the log level to DEBUG for the default logger. This reveals more details that can be useful when troubleshooting (and is very verbose in production).
  • push: configures the server to pre-emptively send resources to the client using HTTP/2 server push.
  • encode: encodes responses using the configured encoding(s). A typical use for encoding is compression
  • respond: writes a hard-coded/static response to the client (used for the health check of the load balancer itself)
  • log: enables and configures HTTP request logging (also known as access logs)
  • reverse_proxy: proxies requests to one or more backends with configurable transport, load balancing, health checking, request manipulation, and buffering options