I am using the beta of Caddy v2 as my reverse proxy. Although it is in beta, it does what I want and works well.
Update: Caddy v2 is now out of beta, so you should use the latest version.
mkdir -p .local/bin && cd .local/bin
# download caddy beta 2
curl -L https://github.com/caddyserver/caddy/releases/download/v2.0.0-beta2/caddy2_beta2_linux_amd64 -o caddy
# make the binary executable
chmod +x caddy
# go back to the home directory where the Caddyfile is stored
cd ~
# allow caddy to bind to low ports (80 and 443)
sudo setcap 'cap_net_bind_service=+ep' /home/ubuntu/.local/bin/caddy
# start caddy with configuration taken from the Caddyfile in the current directory
# run instead of start allows us to use Ctrl-C to kill it if there is a problem with DNS configuration so we do not keep retrying requests to LetsEncrypt.
caddy run
I am using a Caddyfile to configure it. It can be as simple as this for each service:
<service-url> {
reverse_proxy * localhost:<port>
}