Trouble accessing home assistant behind Nginx

Hi, I’ve been searching for a solution for this but I can’t seem to find it. Nginx works like a charm on other services, but I can’t get it to work with Home Assistant. Would be really happy if someone could look over my config and perhaps see what I am doing wrong. I want Home Assistant to be accessable at https://example.com/hass

Setup is as follows: Nginx running on a Ubuntu VM (192.168.0.110)
Home assistant running inside Qnap container station on my NAS (192.168.0.105:8123)

in configuration.yaml I have set the following:

http:
base_url: /hass/
use_x_forwarded_for: true

And in nginx i have the following:

location /hass {
    return 301 $scheme://$host/hass/;
}
location /hass/ {
	proxy_pass http://192.168.0.105:8123/;
	proxy_set_header Host $host;
	proxy_redirect http:// https://;
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;

}

When I try to access https://example.com/hass now I get an error from HA stating “Home Assistant had trouble connecting to the server” and a bunch of 404 in the dev console in Chrome (screenshot here: https://i.imgur.com/7O5EnAO.jpg)

Any ideas would be really helpful!

Have you tried without the /hass in the path? The screenshots indicate, that it’s trying to access resources from the root (without /hass/ in the beginning).

Yes, without /hass (https://example.com) displays my frontpage index.html (which it should). The index.html contains just two hyperlinks and a picture.

What I meant was if you tried with
location / {
instead of
location /hass/ {
The files you’re getting the 404 for would be at /hass/foo, but it’s trying to get them from /.

Oh, right :slight_smile: That gives me a duplicate location error, since location / is already used.

Here’s the complete nginx config, service1 and service2 works as they should.
server {
listen 80 default_server;
listen [::]:80 default_server;

	root /var/www/html;

		index index.html index.htm;

	server_name redacted ;

	location / {
		# First attempt to serve request as file, then
		# as directory, then fall back to displaying a 404.
		try_files $uri $uri/ =404;
	}
#Stats	
 	location /service1 {		
		return 301 $scheme://$host/service1/;		
}
	location /service1/ {
		proxy_pass http://192.168.0.110:8181;
		proxy_set_header Host $host;
		proxy_set_header X-Forwarded-Host $server_name;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header X-Forwarded-Ssl on;
		proxy_set_header X-Forwarded-Proto $scheme;
		proxy_read_timeout  90;
		proxy_redirect http://192.168.0.110:8181 https://$host;
}
    location /hass {
        return 301 $scheme://$host/hass/;
    }
    location /hass/ {
	    proxy_pass http://192.168.0.105:8123/;
	    proxy_set_header Host $host;
        proxy_redirect http:// https://;
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
}
    location /service2 {
        return 301 $scheme://$host/service2/;
    }
    location /service2/ {
        proxy_pass http://192.168.0.100:5000;
        proxy_max_temp_file_size 0;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Host $server_name;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Ssl on;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout  90;
        proxy_redirect http://192.168.0.100:5000 https://$host;
    }

So then you could try to, at least temoprarily, set the other location to something else. Just to make sure HA works with using the plain / as its root.

I edited in the whole nginx-config, mind taking a look? :slight_smile:

Comment out that part. And change location /hass/ to location /

Yeah, that works, Home Assistant is now available at https://example.com :slight_smile:

but how can i get it to work at example.com/hass?

I have never tried it myself. But apparently HA is not able to work anywhere else besides the root of the domain. Maybe there’s some workaround, but I don’t know about that.

Alright, thanks for the help anyway, very apprieciated! How about setting it up as a sub-domain, for example hass.example.com, would that be any better?

I run Hass services using a hostname in my own personal domain - in fact I use many hostnames like this for external access to internal services - also to use an SSL certificate and enforce HTTPS across the board. The Hass server itself is never directly connected to by any clients and has itas own host name which is part of my internal scheme. ( Strictly, in “hass.REDACTED.net”, “hass” is a host name in the domain “REDACTED.net”. “Hass.REDACTED.net” is colloquially called a subdomain, of course - and if the zone files were so arranged it would be an actual subdomain, but that’s too complex for this set-up).

Each internal service has an Nginx virtual server config file of its own. For Hass its definition looks like this:

upstream hass {
    server 192.168.1.100:8123;    # the hass server and port inside the network
    }

    server {
        listen       192.168.1.77:443 ssl;    # the NGINX server IP and listening port
        server_name  hass.REDACTED.net;    # The host header to listen for
        root         /usr/share/nginx/html;
        include      /etc/nginx/sslcerts.conf;
        proxy_buffering off;
        rewrite   ^/robots.txt$    https://REDACTED.net/robots.txt last; # All robots please go away

        location /.well-known/ {
                proxy_pass http://127.0.0.1:81/.well-known/;  # Let's encrypt validation
                        }

        location / {
            proxy_pass http://hass;    # Matches to the "upstream" name above
            proxy_set_header Host $host;
            proxy_redirect http:// https://;
            proxy_http_version 1.1;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  # for forcing password validation from outside
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
            }
    }

and for completeness, the ssl certs (uses a SAN cert from Let’s Encrypt) file included above looks like this:

    ssl_certificate "/etc/dehydrated/certs/REDACTED.net/fullchain.pem";
    ssl_certificate_key "/etc/dehydrated/certs/REDACTED.net/privkey.pem";
    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout  10m;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    ssl_dhparam /etc/nginx/dhparams.pem;

There is also a virtual server listening on any requests that arrive on port 80 (i.e. unencrypted) and causes a 301 response to tell the client to re-request to the HTTPS listener. By means of multiple virtual server files I can distribute any incoming requests, by reading the host header of the request, to any back-end I need to - all using one public facing IP address. Users outside my network all resolve all host names for the domain using a wildcard to a single IP address, so I can use any host name at the REDACTED.net domain that I want for no extra work.

Thanks for a great, detailed reply! I set it up as home.example.com now and seems that its working :slight_smile: