Reverse proxy with NGINX using a subdomain

:warning: This guide has been migrated from our website and might be outdated. Feel free to edit this guide to update it, and to remove this message after that.

This example demonstrates how you can configure NGINX to act as a proxy for Home Assistant.

This is useful if you want to have:

  • a subdomain redirecting to your Home Assistant instance
  • several subdomains for several instances
  • HTTPS redirection

Subdomain

So you already have a working NGINX server available at example.org. Your Home Assistant is correctly working on this webserver and available at http://localhost:8123

To be able to access to your Home Assistant instance by using https://home.example.org, create file /etc/nginx/sites-enabled/homeassistant (or symlink via /etc/nginx/sites-available) and add the following:

server {
    listen       443 ssl;
    server_name  home.example.org;

    ssl on;
    ssl_certificate /etc/nginx/ssl/home.example.org/home.example.org-bundle.crt;
    ssl_certificate_key /etc/nginx/ssl/home.example.org/home.example.org.key;
    ssl_prefer_server_ciphers on;

    location / {
        proxy_pass http://localhost:8123;
        proxy_set_header Host $host;

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

    location /api/websocket {
        proxy_pass http://localhost:8123/api/websocket;
        proxy_set_header Host $host;

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

    }
}

If you don’t want HTTPS, you can change listen 443 ssl to listen 80 or better, consider redirecting all HTTP to HTTPS. See further down.

Multiple Instance

You already have Home Assistant running on http://localhost:8123 and available at home.example.org as describe before. The configuration file for this Home Assistant is available in /home/alice/.homeassistant/configuration.yaml.

You want another instance available at https://countryside.example.org

You can either:

  • Create a new user, bob, to hold the configuration file in /home/bob/.homeassistant/configuration.yaml and run Home Assistant as this new user
  • Create another configuration directory in /home/alice/.homeassistant2/configuration.yaml and run Home Assistant using hass --config /home/alice/.homeassistant2/

In both solution, change port number used by modifying configuration.yaml file.

http:
  server_port: 8124
  ...

Start Home Assistant: Now, you have another instance running on http://localhost:8124

To access this instance by using https://countryside.example.org create the file /etc/nginx/sites-enabled/countryside.example.org (or symlink via /etc/nginx/sites-available) and add the following:

server {
    listen       443 ssl;
    server_name  countryside.example.org;
 
    ssl on;
    ssl_certificate /etc/nginx/ssl/countryside.example.org/countryside.example.org-bundle.crt;
    ssl_certificate_key /etc/nginx/ssl/countryside.example.org/countryside.example.org.key;
    ssl_prefer_server_ciphers on;

    location / {
        proxy_pass http://localhost:8124;
        proxy_set_header Host $host;

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

    location /api/websocket {
        proxy_pass http://localhost:8124/api/websocket;
        proxy_set_header Host $host;

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

    }
}

HTTP to HTTPS redirection

Add to your /etc/nginx/sites-enabled/default

server {
    listen       80 default_server;
    server_name  example.tld;

    return 301 https://$host$request_uri;
}
5 Likes

If i have an home assistant installed as docker is possible to configure an nxing docker container to make this to work?

Yes, that’s what I do. I use the linuxserver/swag docker, which also uses letsencrypt.

Hello, I want to configure nginx to change ipv6 of a client by an ipv4. Did you know how ?

Exactly what I needed, thanks!

After setting up reverse proxy, add-ons does not work correctly (for example, the esphome addon does not save config files, vcode does not show types in the code - it does not color lines). Some addons (for example hacs) don’t work at all. The reason for this behavior is not clear. What can reverse proxy be missing? tried to change timers - no result.

Did you find any workaround? I have same problem

yes. in my case nginx option like some header, buffer size, request length and other be not compatible.
make delete add_header Strict-Transport-Security

I have homeassistant installed in rpi and have it currently setup using duckdns and letsencrypt. I just setup a new ubuntu server and installed Nextcloud. How do I go about using Nginx and setup so I can use both home assistant and the new ubuntu server? I tried few options and none of them worked. So then stumbled upon nginx but no idea where to start and if I should set up nginx in HA or ubuntu server and how I can still get the redirection as needed.

Thank you so much. My nginx home assistant config was very similar to your. However, I was missing the below section. After I added that to my config, it cleared up a couple of issues I was having related to remote access (mentioned below).

location /api/websocket {
...
}

I WAS getting intermittent “Login attempt or request with invalid authentication from…” notifications instigated by my mobile devices with Home Assistant Companion installed. Also, the sensors from these mobile apps were sometimes not able to update their respective entities in Home Assistant.

Anyway, below is my updated nginx config, it also includes the config to add glances remote access as well: http://countryside.example.org/glances

    server {
            listen 443 ssl http2; 
            listen [::]:443 ssl http2;
            ssl_certificate     ./ssl/fullchain.cer;
            ssl_certificate_key ./ssl/cert.key;
            ssl_prefer_server_ciphers on;
            server_name  countryside.example.org;
            location / {
                proxy_pass http://192.168.1.198:8123;
                proxy_set_header Accept-Encoding "";
                proxy_set_header Host $host;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection $http_connection;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;

                port_in_redirect off;
                location /glances/ {
                    rewrite /glances/(.*) /$1 break;
                    proxy_pass http://localhost:61208/;
                    proxy_set_header Accept-Encoding "";
                    proxy_set_header Host $host;
                    proxy_http_version 1.1;
                    proxy_set_header Upgrade $http_upgrade;
                    proxy_set_header Connection $http_connection;
                    proxy_set_header X-Real-IP $remote_addr;
                    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                    proxy_set_header X-Forwarded-Proto $scheme;
                }
            }

            location /api/websocket {
                proxy_pass http://192.168.1.198:8123/api/websocket;
                proxy_set_header Accept-Encoding "";
                proxy_set_header Host $host;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection $http_connection;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
            }
    }

I’m using Nginx Proxy Manager and tried to input part of your config there to get the /glances/ working, so this part:

                location /glances/ {
                    rewrite /glances/(.*) /$1 break;
                    proxy_pass http://localhost:61208/;
                    proxy_set_header Accept-Encoding "";
                    proxy_set_header Host $host;
                    proxy_http_version 1.1;
                    proxy_set_header Upgrade $http_upgrade;
                    proxy_set_header Connection $http_connection;
                    proxy_set_header X-Real-IP $remote_addr;
                    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                    proxy_set_header X-Forwarded-Proto $scheme;
                }

It seems to accept this config in the Custom location additional settings, but the glance views do not appear to become available.

EDIT: It does seem to work after all, just needed to clear my browser cache! However, it only works exactly once after clearing cache. After a few seconds HA page refreshes (crashes) and after that the glances do not work anymore. Also found this alternative, which seems to work identically: Reverse proxy to the Glances Web UI · nicolargo/glances Wiki · GitHub

Can you elaborate what the part proxy_pass http://localhost:61208/; is doing? Should I have something extra running on the NPM server?