A reverse proxy provides multiple benefits:
- A reverse proxy can easily allow multiple services to be hosted by one IP address. When an HTTP request comes in, a reverse proxy can follow rules to determine what to do with the request (silently pass the request to another port on the same machine OR another machine, return an error, or even serve static content directly).
- A reverse proxy can act as a single point of HTTPS (TLS) termination. Rather than set up HTTPS on every service you set up, you can make it so that they are only accessible through the reverse proxy, and the reverse proxy handles the cert (typically a wildcard, often from LetsEncrypt).
- A reverse proxy can apply security settings - like HSTS, Clickjacking Protection headers, etc. - through all services that come through it.
- A reverse proxy reduces the public footprint by making only one port externally accessible. You can quickly disable the proxy (or traffic forwarding to it) in case of an emergency.
- A reverse proxy can enforce some simple authentication. For example, if you have a completely unprotected HTTP app, a proxy can provide basic HTTP authentication protection.
Personally, I use Caddy v2 for my homelab. I don't think it's perfect, but until I go full Kubernetes, it's pretty close. The Caddyfile format is simple (but not really machine editable). It makes HTTPS via LetsEncrypt very easy. I don't have a guide that I can easily link - maybe I should write one some day - but I can give you a quick example of my setup. Also, their getting started guide is a decent starting point.
I deploy Caddy as a docker container using docker-compose (see docker-compose.yml).
The volumes will need to be setup (data, config and logs are folders; the rest are specific files). Also, I port forward my router's 443 to 55443 (and 80 to 55080) since this machine is running another tool that needs 443. (GENERALLY, using multiple services on one machine, I find it useful to NOT use low numbered/defined ports unless there's a good reason). It's using a Dockerfileto build caddy with a couple plugins. This is their recommended Docker deploy method if using plugins.
I use Route53 DNS for a wildcard Let's Encrypt certificate. I have a regular DNS entry to forward to my local DNS, and an external tool that handles that. Caddy, however, gets a copy of the .aws-creds (see GH Gist).
Then, my basic Caddyfile is just in charge of telling it to look for more Caddyfiles.
Finally, each tool has a Caddyfile in the sites folder. For example, Jellyfin in jellyfin-example.caddy.
That Caddyfile applies a bunch of protection headers. I do this at the per-tool level since some headers may break some tools.
Finally, I deploy it with:
sudo docker-compose up -d
Then, I update it with:
sudo docker-compose build
sudo docker-compose up -d
I can shut it down with:
sudo docker-compose down
If I just want to reload new sites, Caddy can do that without a full restart that breaks connections:
docker exec -it caddy2 caddy reload --config /etc/caddy/Caddyfile --adapter caddyfile
Note that this is a bit sloppy, since it relies on the container name; I should redo it to use the docker-compose config.
There's half-a-tutorial. :) I can answer questions if you'd like, but Nginx, Traefik, and Apache are all popular as reverse proxies as well.
where's your teapot?