Reverse proxy with https: Nginx Proxy Manager or Caddy
Once you’re running more than a few services (Home Assistant, Jellyfin, a NAS), you don’t want to remember that they’re at 192.168.1.20:8123 and 192.168.1.30:8096. With a reverse proxy, they get a regular name, like ha.yourdomain.com, a valid https certificate, and one place to manage it all.
What do you need?
- A domain name (a few euros per year) where you can manage the DNS.
- A computer or container for the proxy, with a fixed IP address.
- If you want to access services from outside: ports 80 and 443 forwarded to the proxy. Only do this for services that really need to be public, and preferably not without extra security. For external access with less risk, choose a VPN.
- Want https only internally? Then use the “DNS challenge” from your DNS provider to get certificates, without needing port 80 open, and have your own DNS (like Pi-hole) point the name to the proxy.
Option 1: Nginx Proxy Manager
A web page where you click everything. Put this in a compose.yaml and start with docker compose up -d:
services:
npm:
image: jc21/nginx-proxy-manager:latest
restart: unless-stopped
ports:
- "80:80"
- "81:81"
- "443:443"
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
- Open
http://IP-address:81and create an admin account (older versions start withadmin@example.comand passwordchangeme; change it immediately). - Choose Hosts → Proxy Hosts → Add Proxy Host. Fill in the name (
ha.yourdomain.com), the address and port of the service, and turn on Websockets Support. - On the SSL tab, request a new Let’s Encrypt certificate and turn on Force SSL.
Option 2: Caddy
Caddy handles certificates itself and your configuration is a small file. Put this in Caddyfile:
ha.yourdomain.com {
reverse_proxy 192.168.1.20:8123
}
jellyfin.yourdomain.com {
reverse_proxy 192.168.1.30:8096
}
And start Caddy in Docker with your Caddyfile and a folder for the data:
services:
caddy:
image: caddy:2
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- ./caddy-data:/data
- ./caddy-config:/config
Caddy requests the certificates itself as soon as the name points to your address and the ports are accessible.
Home Assistant behind a proxy
Home Assistant refuses connections through a proxy unless you allow it. Put the address of your proxy in configuration.yaml:
http:
use_x_forwarded_for: true
trusted_proxies:
- 192.168.1.10
Restart Home Assistant afterwards. Use the IP address of the proxy here, not your entire network.
Checking and troubleshooting
- Check your certificate with our SSL check and use the HTTP headers tool to see if http redirects properly to https and which security headers your site sends.
- 502 Bad Gateway: the proxy can’t reach the service. Check the address, the port, and whether the service is running.
- Certificate failed: does the name point to the correct address (check with the DNS lookup) and are ports 80 and 443 accessible?
- Websockets failing: turn on the option for websockets, otherwise things like the Home Assistant dashboard won’t work properly.
Security
- Only put services online that you really need from outside, and keep them updated.
- Use strong passwords and, where possible, a second factor (2FA).
- Don’t make admin pages (like port 81 of Nginx Proxy Manager) accessible from outside.
Sources and attribution
This article is written in our own words. Further reading:
- Nginx Proxy Manager;
- Caddy documentation;
- Home Assistant’s HTTP integration, with explanation about proxies.