I run nginx as my reverse proxy of choice from the folks over at linuxserver.io with automated Let's Encrypt functionality. It plugs neatly into the 20 or so containers I run on my primary server VM and the thought of migrating over the in-built Home Assistant plus reconfiguring all my configs made me go weak at the fingertips.

My fully Ansiblised home infrastructure is open sourced at github.com/ironicbadger/infra including all my reverse proxy configs

I was running into an issue for a while tonight where I could get Home Assistant itself working just fine but any add-ons that used web sockets wouldn't load properly.

Node-RED (pictured above) would load but the connection would always fail after a few seconds (in fact it never loaded). The iFrame for VSCode just refused to do anything.

To diagnose the issue was with the reverse proxy and not Home Assistant or the add-ons in question was simple. Browse to the IP address version of the web interface such as http://192.168.1.99:8123 and if everything works fine, it's the reverse proxy. This was the case for me.

Next I moved onto Google, then various Discord servers before getting a common theme that these add-ons required websockets connections. Eventually I found this post in a Github issue which led me to fix needed.

The important section was to include proxy_set_header in both location blocks. So in both / and /api/websocket.

	proxy_set_header Upgrade $http_upgrade;
	proxy_set_header Connection "upgrade";

After I did this and restarted the proxy, everything worked as expected.

Here is the full homeassistant.conf used by nginx:


server {
	listen 443 ssl;
	listen [::]:443 ssl;

	server_name ha.*;

	include /config/nginx/ssl.conf;

	client_max_body_size 0;

	# enable for ldap auth, fill in ldap details in ldap.conf
	#include /config/nginx/ldap.conf;

	location / {
		# enable the next two lines for http auth
		#auth_basic "Restricted";
		#auth_basic_user_file /config/nginx/.htpasswd;

		# enable the next two lines for ldap auth
		#auth_request /auth;
		#error_page 401 =200 /login;

		include /config/nginx/proxy.conf;
		resolver 127.0.0.11 valid=30s;
		set $upstream_homeassistant 192.168.1.99;
		proxy_pass http://$upstream_homeassistant:8123;

		proxy_set_header Upgrade $http_upgrade;
		proxy_set_header Connection "upgrade";
	}

	location /api/websocket {
		resolver 127.0.0.11 valid=30s;
		set $upstream_homeassistant 192.168.1.99;
		proxy_pass http://$upstream_homeassistant:8123;
		proxy_set_header Host $host;

		proxy_http_version 1.1;
		proxy_set_header Upgrade $http_upgrade;
		proxy_set_header Connection "upgrade";
	}
}