Before I had a reverse proxy, accessing my home services meant remembering port numbers. Plex was :32400, Nextcloud was :443, Vaultwarden was :8081, AdGuard Home was :3000. Every new service added another number to remember, and accessing anything remotely meant port forwarding each one individually.
A reverse proxy cleans all of that up. One port open to the internet (443), clean subdomain URLs, automatic SSL certificates, and a single place to manage access control. Here’s how I set it up and what I learned.
What a Reverse Proxy Actually Does
The simplest way to think about it: a reverse proxy sits in front of all your services and routes incoming requests based on the hostname. A request to nextcloud.yourdomain.com hits the proxy, which looks up the routing rule and forwards it to the Nextcloud container on your internal network. The browser sees a clean URL and a valid SSL certificate. The actual service can be running on any internal port.
You only need one public IP address and one open port (443). Everything else lives internally. From the internet’s perspective, all your services are accessible at the same IP.
The Tool I Use: Nginx Proxy Manager
I use Nginx Proxy Manager (NPM). It’s a Docker container that puts a web UI on top of nginx configuration. You add a proxy host, point it at your internal service, and it handles the nginx config and SSL certificate automatically via Let’s Encrypt.
NPM is the right tool for most home users. It’s not as powerful as configuring nginx directly, but for routing a dozen services it’s much less painful. The UI is clean and the SSL certificate management is nearly hands-off.
The alternative worth knowing about is Caddy, which does automatic HTTPS without the UI layer. If you’re comfortable with a config file, Caddy is more elegant. If you want a clickable interface, NPM wins.
The Domain Setup
You need a real domain name. Internal-only setups can work with a self-signed CA, but if you want valid SSL certificates and remote access, you need a domain you own and control.
I use a subdomain structure: all my services are under home.mydomain.com. Each service gets its own subdomain: nextcloud.home.mydomain.com, jellyfin.home.mydomain.com, etc. This keeps home services organized under one branch of the domain tree.
For DNS, I use Cloudflare as the DNS provider. This is important for two reasons: the Cloudflare API lets NPM get wildcard SSL certificates automatically (one cert covers all subdomains), and I can use Cloudflare’s proxy to hide my home IP address from public DNS lookups.
Port Forwarding and the Security Question
To make any service accessible from outside your home network, you need to forward port 443 from your router to the machine running NPM. This is the part most homelab guides gloss over – you’re punching a hole in your network’s perimeter.
Before forwarding anything, think about what you’re actually exposing. NPM sits in front of your services, but it’s another piece of software that needs to be kept updated. Services behind NPM are only as secure as those services themselves.
My approach: most services are only accessible internally. The proxy adds local hostnames (jellyfin.home) that resolve to the server’s LAN IP. External access requires going through Tailscale VPN instead of a port-forwarded entry point. Only a few services – the ones I actually need to reach remotely without a VPN – are exposed publicly, and those require additional authentication.
Tailscale as an Alternative
For most people, Tailscale is a better answer than a traditional reverse proxy for remote access. Install the Tailscale Docker container on your Unraid server, install Tailscale on your phone and laptop, and all your services are reachable on a private VPN network without any port forwarding.
The Tailscale approach means nothing is exposed to the public internet. The tradeoff is that you need Tailscale installed on every device that needs access, and it doesn’t work for sharing services with people who won’t install Tailscale.
I use both: NPM for local hostname routing and a handful of publicly-accessible services, Tailscale for everything I want remote access to without public exposure.
The SSL Certificate Part
NPM handles Let’s Encrypt SSL certificates automatically. For each proxy host you configure, you click “Request new SSL certificate” and it handles the ACME challenge. With Cloudflare DNS challenge, wildcard certificates work cleanly.
The certificates auto-renew before expiration. I’ve had NPM running for two years and I’ve never manually renewed a certificate. This part just works.
What I’d Do Differently
I’d start with Tailscale before setting up a public reverse proxy. The VPN approach is simpler, more secure, and requires less ongoing attention. A public-facing reverse proxy adds complexity and attack surface that most home users don’t need.
If you do go the public route, get a proper router with a decent firewall. The GL.iNet GL-MT6000 running OpenWrt is what I use, and having proper firewall rules visible in the router UI – rather than buried in a consumer router’s settings – makes a real difference for understanding what’s actually exposed.
Next: the hardware I actually recommend for a starter homelab, without the aspirational gear nobody needs.
Products mentioned in this post:
Affiliate disclosure: Some links in this post are Amazon affiliate links. If you buy through them, I get a small commission at no cost to you. It helps keep the lights on here.
Leave A Comment