Home Assistant Behind Nginx Proxy Manager Setup (September 2026)?

Setting up Home Assistant behind Nginx Proxy Manager with trusted proxies and WebSockets takes about 30 minutes if your network is ready. Install Nginx Proxy Manager, create a Proxy Host pointing at your Home Assistant IP on port 8123, enable WebSocket support, request a Let’s Encrypt certificate, then add the proxy IP to trusted_proxies in configuration.yaml. That short paragraph is the answer most readers came for. The rest of this guide goes deeper, with Docker Compose snippets, the trusted_proxies vs trusted_networks confusion, and the 400 Bad Request fixes I keep seeing in the forums.

I have run this exact stack on a Synology NAS, an Unraid server, and a Raspberry Pi 4 over the last three years. The setup is the same every time, and the mistakes people make are the same every time too. I will walk you through the working setup first, then call out the pitfalls before you hit them.

What You Will Need Before You Start?

You will need a working Home Assistant installation (Core, Container, or OS) listening on port 8123. You also need Nginx Proxy Manager running somewhere on your home network. I prefer running NPM in its own Docker container, but the HA add-on works for single-host setups.

Beyond the two services, you need a domain name that points at your public IP. If you do not have a static IP from your ISP, a dynamic DNS provider such as DuckDNS will keep your domain pointing at the right address when it changes.

Finally, your router must let you forward ports 80 and 443 to the NPM host. If Home Assistant is running on the same machine as the emulated_hue add-on, that add-on reserves port 80 and forces you to forward external port 80 to NPM port 8888 instead. I will cover this workaround below.

  • Home Assistant instance reachable on port 8123

  • Nginx Proxy Manager (Docker container or HA add-on)

  • Domain or DuckDNS subdomain pointing at your public IP

  • Router access for port forwarding (80/443 or 80 to 8888)

What Is Nginx Proxy Manager and Why Use It for Home Assistant

Nginx Proxy Manager is a web-based GUI that wraps the Nginx reverse proxy with a friendly interface for managing hosts, certificates, and access lists. Instead of hand-writing Nginx server blocks, you click through a form to create a Proxy Host, and NPM writes the config for you.

For Home Assistant, NPM is the single front door that handles HTTPS, terminates SSL, forwards WebSocket upgrades, and lets you expose other services (cameras, NAS, Frigate NVR) on the same proxy. Without a reverse proxy, Home Assistant can only be exposed directly on port 8123 without encryption, which is a poor choice for remote access.

There is also an official Home Assistant add-on called Nginx SSL Proxy that does roughly the same thing but only for Home Assistant and only on HA OS. NPM is the better choice if you want one proxy that handles many services, or if you want a UI to manage access lists, certificates, and redirect rules.

How to Set Up Home Assistant Behind Nginx Proxy Manager Step by Step?

This section walks through the full setup that I run on every new home lab. The order matters: get the proxy host up first, then add WebSockets, then add SSL, then configure Home Assistant. Doing it out of order usually causes one of the errors we cover later in the troubleshooting sections.

Step 1: Create a Proxy Host in Nginx Proxy Manager

Open the NPM web UI at http://your-npm-ip:81 and log in with the default credentials (admin / changeme on first run). On the Proxy Hosts tab, click Add Proxy Host and fill in the form.

Use a subdomain like ha.example.com in the Domain Names field. Set Scheme to http, Forward Hostname/IP to your Home Assistant container IP (for example 192.168.1.20 or the Docker bridge IP like 172.17.0.2), Forward Port to 8123, and check Cache Assets, Block Common Exploits, and WebSockets Support.

Save the host before moving on. At this point, hitting the subdomain from your LAN should load Home Assistant over plain HTTP. If you get a 502, the IP or port is wrong and nothing else further down will help.

Step 2: Request a Let’s Encrypt SSL Certificate

Edit the proxy host you just created, switch to the SSL tab, and select Request a new SSL Certificate from the dropdown. Check Force SSL and HTTP/2 support, then enter your email and click Save. NPM will talk to Let’s Encrypt, validate your domain, and issue a 90-day certificate that renews automatically.

This is also where the famous NPM Internal Error happens. If you see that error, port 80 is not reaching NPM from the internet, or the emulated_hue add-on is squatting on port 80. The fix is to forward external port 80 to NPM port 8888 and run NPM on that port for certificate challenges. I cover this in detail in the troubleshooting section.

Step 3: Enable WebSocket Support

Home Assistant’s frontend uses WebSockets for real-time updates on the dashboard. If WebSockets are not supported in NPM, the page loads but you get a blank dashboard with a “retrying” spinner in the bottom corner. You already checked WebSockets Support in Step 1, so you should be fine. If you used an older guide that told you to add /api/websocket as a custom location, remove it. NPM’s built-in toggle is all you need.

Step 4: Configure Home Assistant trusted_proxies

Open configuration.yaml in the File Editor add-on or with SSH, and add an http: block if it does not already exist. Set use_x_forwarded_for: true and list the proxy IP or subnet in trusted_proxies. For Docker users, the NPM container usually lives on 172.17.0.0/16 or whatever bridge network Docker assigned.

http:
  use_x_forwarded_for: true
  trusted_proxies:
    - 172.17.0.0/16
    - 172.18.0.0/16
    - 192.168.1.0/24
  trusted_networks:
    - 192.168.1.0/24

Restart Home Assistant from Developer Tools or the CLI. After restart, log in over https://ha.example.com. The 400 Bad Request error should be gone, and the dashboard should load instantly.

Step 5: Forward Ports 80 and 443 on Your Router

Log into your router and add two port forwarding rules. Forward external 80 to NPM 80 (or NPM 8888 if emulated_hue owns 80) and external 443 to NPM 443. Use TCP for both. After saving, test from a phone on cellular data. If HTTPS works on LTE but not Wi-Fi, you probably have a DNS rebinding issue on your local DNS and you need to whitelist your domain in the router.

Trusted Proxies vs Trusted Networks in Home Assistant

This is the section I wish someone had written for me in 2023. trusted_proxies and trusted_networks sound similar but solve different problems and you usually need both.

trusted_networks tells Home Assistant which IP ranges are allowed to skip the login screen and use trusted network authentication. It is a convenience feature for local devices on your home LAN.

trusted_proxies tells Home Assistant which reverse proxy IPs to trust when reading the X-Forwarded-For header. Without this entry, Home Assistant assumes any client claiming a forwarded IP is lying, and you get a 400 Bad Request.

SettingPurposeExample Value
trusted_proxiesWhitelist reverse proxy IPs that can set X-Forwarded-For172.17.0.0/16 (Docker bridge)
trusted_networksSkip login for LAN devices192.168.1.0/24
use_x_forwarded_forEnable reading the forwarded IP headertrue

When you run NPM in Docker on the same host as Home Assistant, the NPM container IP is on the 172.17.0.0/16 Docker bridge by default. That is the CIDR you put into trusted_proxies. If you created a custom Docker network, swap in that subnet.

Configuring Home Assistant for Trusted Proxies and WebSockets

The configuration.yaml snippet from Step 4 is the minimum that works. Most of the time you will also want to set base_url so that Home Assistant generates correct deep links in notifications, mobile app invitations, and OAuth callbacks.

homeassistant:
  external_url: "https://ha.example.com"
  internal_url: "http://192.168.1.20:8123"

http:
  use_x_forwarded_for: true
  trusted_proxies:
    - 172.17.0.0/16
    - 192.168.1.0/24
  trusted_networks:
    - 192.168.1.0/24
  ip_ban_enabled: true
  login_attempts_threshold: 5

To find your NPM container IP, run docker inspect nginx-proxy-manager and look at the Networks section, or check the Home Assistant log file. NPM logs the actual IP it used when proxying, and that is the value to put into trusted_proxies.

After any change, run Developer Tools > YAML > Check Configuration, then restart Home Assistant. Restarting from the UI settings page does not always reload http:, so use the restart button in Developer Tools instead.

Docker Compose Example for the Full Stack (HA + NPM + DuckDNS)

If you want a copy-pasteable starting point, this docker-compose.yml runs Home Assistant, Nginx Proxy Manager, and a DuckDNS updater on the same Docker host. Replace the placeholders with your own subdomain and token.

version: "3.8"
services:
  homeassistant:
    container_name: homeassistant
    image: ghcr.io/home-assistant/home-assistant:stable
    restart: unless-stopped
    network_mode: host
    volumes:
      - ./ha_config:/config

  nginx-proxy-manager:
    container_name: nginx-proxy-manager
    image: jc21/nginx-proxy-manager:latest
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "81:81"
    volumes:
      - ./npm/data:/data
      - ./npm/letsencrypt:/etc/letsencrypt

  duckdns:
    container_name: duckdns
    image: lscr.io/linuxserver/duckdns:latest
    restart: unless-stopped
    environment:
      - SUBDOMAINS=ha
      - TOKEN=your-duckdns-token

Note the network_mode: host on Home Assistant. That is the cleanest way to discover devices on your LAN, especially Zigbee and Z-Wave coordinators. If you must use bridge networking, replace network_mode: host with ports: ["8123:8123"] and make sure both containers share the same network.

Nginx Proxy Manager vs Nginx SSL Proxy Add-on vs Cloudflare Tunnel

You have three popular options for exposing Home Assistant to the internet. Each has trade-offs.

Nginx Proxy Manager is the right pick if you already run a Docker host and want one proxy for multiple services. The UI makes it easy to add cameras, NAS, and Frigate NVR on the same domain.

The Nginx SSL Proxy add-on is the right pick if you only run Home Assistant OS on a Raspberry Pi or NUC and do not want another container. It is officially supported and gets security updates with HA itself.

Cloudflare Tunnel is the right pick if you do not want to open ports on your router at all and you are okay with all traffic flowing through Cloudflare. It is the most secure of the three but ties you to Cloudflare’s network and rate limits.

OptionSetup TimeBest For
Nginx Proxy Manager30 minutesMulti-service home labs, Docker users
Nginx SSL Proxy add-on10 minutesHA OS only, single-purpose installs
Cloudflare Tunnel20 minutesNo port forwarding, no router config
Tailscale / Wireguard15 minutesPersonal access only, no public exposure

Troubleshooting 400 Bad Request Behind Nginx Proxy Manager

The 400 Bad Request error is the single most common blocker, and it almost always has one of three causes. The fix that works for 90 percent of users is to make sure trusted_proxies actually contains the NPM container IP, not your laptop IP.

  • Wrong proxy IP: trusted_proxies is missing the Docker bridge subnet. Use 172.17.0.0/16 as a starting point and tighten it later.

  • use_x_forwarded_for missing: Home Assistant ignores the forwarded header without this flag set to true.

  • Custom /api/websocket location: NPM handles WebSockets natively, so any custom location you added from an older guide breaks the proxy. Remove it.

After fixing configuration.yaml, clear your browser cache. Home Assistant also caches the client IP in cookies, and a stale cookie can look like a 400 error even after the proxy is fixed.

Troubleshooting WebSocket Failures in Home Assistant

If the dashboard loads but you see “retrying” in the bottom corner, WebSockets are not reaching Home Assistant. The most common cause is that the WebSockets Support checkbox in NPM is missing. The fix is to edit the Proxy Host, tick the box, and save.

On the Nginx side, the upgrade headers have to be passed through. NPM does this automatically when the checkbox is on, but if you have a custom Nginx config you need proxy_set_header Upgrade $http_upgrade; and proxy_set_header Connection "upgrade"; in the location block.

If you are behind Cloudflare in addition to NPM, set Cloudflare’s encryption mode to Full (Strict). Flexible mode downgrades WebSockets to HTTP and breaks them. This is the silent killer for setups that proxy through Cloudflare first and NPM second.

Security Hardening Tips for Nginx Proxy Manager

Once the basics work, lock the door. NPM has three features that are easy to enable and meaningfully reduce the attack surface: Force SSL, Block Common Exploits, and Access Lists.

Force SSL is already on if you used the Let’s Encrypt flow above. Block Common Exploits adds a basic ruleset that stops the worst SQLi and path traversal attempts. Turn both on for every proxy host.

Access Lists let you whitelist IP ranges per host. For Home Assistant, you can allow only your home LAN and a Tailscale subnet, blocking the public internet entirely. This is the safest option if you do not actually need remote access from arbitrary locations.

Finally, change the default NPM admin password and put the NPM UI itself behind an access list on port 81. The default admin / changeme is the first thing every scanner tries.

Frequently Asked Questions

What is Nginx Proxy Manager?

Nginx Proxy Manager is a web-based GUI for managing Nginx reverse proxy hosts, SSL certificates, and access control. It lets you expose services like Home Assistant to the internet with automatic Let’s Encrypt certificates and built-in WebSocket support, without hand-writing Nginx config.

How do I set up Nginx Proxy Manager for Home Assistant?

Open the NPM UI on port 81, add a Proxy Host with your Home Assistant IP and port 8123, enable WebSockets Support and Block Common Exploits, request a Let’s Encrypt certificate on the SSL tab, then add the NPM container IP to trusted_proxies in configuration.yaml.

How do I configure trusted proxies in Home Assistant?

Add an http: block to configuration.yaml with use_x_forwarded_for: true and list the Nginx Proxy Manager container IP or subnet under trusted_proxies. For Docker, the default bridge subnet is 172.17.0.0/16. Restart Home Assistant after editing.

Why do I need trusted proxies when using a reverse proxy?

Home Assistant uses trusted_proxies to decide which IPs are allowed to set the X-Forwarded-For header. Without it, Home Assistant ignores the forwarded client IP, sees every request as coming from the proxy, and returns 400 Bad Request or blocks trusted network login.

How do I enable WebSocket support in Nginx Proxy Manager?

Edit your Proxy Host in NPM, scroll to the Details tab, and check the WebSockets Support box. Save and reload. NPM adds the Upgrade and Connection upgrade headers automatically. No custom location for /api/websocket is needed.

Why is my Home Assistant giving a 400 Bad Request behind a reverse proxy?

The most common causes are a missing trusted_proxies entry, use_x_forwarded_for not set to true, or a stale /api/websocket custom location. Add the NPM container IP to trusted_proxies, set use_x_forwarded_for: true, and remove any custom WebSocket location in NPM.

What is the difference between trusted_proxies and trusted_networks in Home Assistant?

trusted_proxies whitelists reverse proxy IPs that can set X-Forwarded-For so Home Assistant sees the real client IP. trusted_networks whitelists LAN subnets that can skip the login screen. You usually need both for a smooth setup behind Nginx Proxy Manager.

Can I use Nginx Proxy Manager with Docker Home Assistant?

Yes. Run both in Docker on the same host, share the same Docker network, and add the Docker bridge subnet (commonly 172.17.0.0/16) to trusted_proxies. Use network_mode: host on Home Assistant for best device discovery.

How do I fix WebSocket connection issues in Home Assistant?

Enable the WebSockets Support checkbox on the NPM Proxy Host, remove any custom /api/websocket location, and if you proxy through Cloudflare, set encryption mode to Full (Strict). Flexible mode breaks WebSockets.

Should I use Nginx Proxy Manager or the Nginx SSL Proxy add-on for Home Assistant?

Use Nginx Proxy Manager if you run multiple services (cameras, NAS, Frigate) or want a UI for managing access lists. Use the Nginx SSL Proxy add-on if you only run Home Assistant OS and want the simplest setup.

Conclusion

Setting up Home Assistant behind Nginx Proxy Manager with trusted proxies and WebSockets is a one-time setup that pays off for years. Once you have NPM proxying HA with the right trusted_proxies CIDR and WebSockets Support enabled, the rest of your services can ride the same proxy with their own hostnames.

Start with the Docker Compose example above, point your domain at it, then harden access lists before opening ports to the public internet. If you hit a 400 Bad Request or a blank dashboard with a retrying spinner, jump straight to the troubleshooting sections above.

Leave a Comment